Reputation: 23
I'm using Angular 6 and my database is Firebase. Now I try to show each of the room's names according to its building. For example:
Building A
Room 1
Room 2
Building B
Room 1
Room 2
But every time I try, it will show all the building names first, and only then it will show the room's names. This is what I got for now:
Building A
Building B
Room 1
Room 2
I find out this happens because forEach
keeps skipping the subscribe
function.
I have attempted to use promise
and await
, but it doesn't work. Maybe because I use it in a wrong way? I'm not so sure how to use promise
in a correct way.
async loadData(){
this.navigationService.user
.subscribe( user => {
console.log(user);
this.user = user;
this.navigationService.getBuildings(this.user.orgId)
.subscribe( building => {
this.navMasterBuilding = [];
this.buildings = building;
this.buildings.forEach( async building2 => {
this.completeBuildingId = building2.completeBuildingId;
this.buildingName = building2.buildingName;
console.log(building2.buildingName);
await new Promise ((resolve, reject) => {
this.navigationService.getLocation(this.user.orgId, this.completeBuildingId)
.subscribe(location => {
console.log('room' + location);
this.navMasterLocation = [];
});
resolve();
});
});
});
});
}
I have try to delay it by using setTimeout, but it still does't work.
Upvotes: 2
Views: 6856
Reputation: 12640
Array.forEach
only works with synchronous functions. Change it to using the for...of
syntax which does work. Next to that you resolve
the Promise
before the call to getLocation
finished and the code in subscribe
ran. Change the code to call resolve
within the getLocation.subscribe
.
for(const building2 of buildings) {
console.log(building2.buildingName);
await new Promise ((resolve, reject) => {
this.navigationService.getLocation(this.user.orgId, this.completeBuildingId)
.subscribe(location => {
console.log('room' + location);
this.navMasterLocation = [];
resolve();
});
});
}
Note that it can be simplified to:
for(const building2 of buildings) {
console.log(building2.buildingName);
const location = await this.navigationService.getLocation(this.user.orgId, this.completeBuildingId).toPromise();
console.log('room' + location);
this.navMasterLocation = [];
}
Also do note that I'm not quite sure why you use this.completeBuildingId
instead of a local variable. Given that it gets overwritten in each iteration this seems a bit useless to me.
Upvotes: 10