I have a subscription inside of a for loop that fetches JSON data as a series of "category data" from an external source, then filters that data based on the users current location. What I need is to wait for all of the subscriptions to complete, and then and only then can my app proceed. Right now, it does not wait for all of the subscriptions to complete, it only completes a few, and then proceeds, while the other subscriptions continue in the background.
I've tried the following "brute force" method, where i know a certain number of categories will be added to the filtered array, and it works, but I don't know how to make it work for any situation.
Here's my code:
getMultipleCategoryData(categoryIds: string[]) {
for (let i = 0; i < this.waypointIds.length; i++) {
//after user selects their categories, its added to waypointNames, and occurences() gets the # of occurences of each waypoint name
let occurences = this.occurences(this.waypointNames[i], this.waypointNames);
this.categoryApi.getCategoryData(this.waypointIds[i]).toPromise().then(data => {
let filteredLocs = data.locations.filter(loc => this.distanceTo(loc, this.hbLoc) < MAX_RADIUS);
let foundLocs = [];
//fill filteredLocs with first n, n = occurences, entries of data
for (let n = 0; n < occurences; n++) {
if (filteredLocs[n] != undefined) {
foundLocs[n] = filteredLocs[n];
}
}
//find locations closest to hbLoc (users current location), and add them to waypoints array
for (let j = 0; j < foundLocs.length; j++) {
for (let k = 0; k < filteredLocs.length; k++) {
if (this.distanceTo(this.hbLoc, filteredLocs[k]) < this.distanceTo(this.hbLoc, foundLocs[j]) && foundLocs.indexOf(filteredLocs[k]) < 0) {
foundLocs[j] = filteredLocs[k];
}
}
}
if (foundLocs.length > 0 && foundLocs.indexOf(undefined) < 0) {
for (let m = 0; m < foundLocs.length; m++) {
this.waypointLocs.push(foundLocs[m]);
}
}
}).then(() => {
//this hardcoded, brute force method works, but i'd need it to be more elegant and dynamic
if (this.waypointLocs.length >= 5) {
let params = { waypointLocs: this.waypointLocs, hbLoc: this.hbLoc };
this.navCtrl.push(MapPage, params);
}
});
}
}
And the categoryApi.getCategoryData method:
getCategoryData(categoryId): Observable<any> {
// don't have data yet
return this.http.get(`${this.baseUrl}/category-data/${categoryId}.json`)
.map(response => {
this.categoryData[categoryId] = response.json();
this.currentCategory = this.categoryData[categoryId];
return this.currentCategory;
});
}
Everything is working fine except waiting for the subscriptions to complete, I'd really like a way to determine when all of the subscriptions have completed. Any help is appreciated!
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…