I am trying to use this service getTodaysRoute() where I figure out what is today’s route node key using .equalTo and from what I understand then I have to use this .on function snapshot from which then I can finally get the key after that I use this key to get data as an observable. The problem happens that the code inside .on function gets executed last and the first time page load my todaysroutekey is undefined. How can I avoid a situation like this?
getTodaysRoute(): Observable<Location[]> {
const date = new Date().toISOString().replace(/T.*/, '');
const userdate = `${this.useremail}${date}`;
let todaysroutekey;
this.db.database
.ref()
.child('routes')
.orderByChild('user_date')
.equalTo(userdate)
.on('child_added', function ( snapshot) {
todaysroutekey = snapshot.key;
});
console.log(todaysroutekey);
return this.db
.list(`${this.routesUrl}/${todaysroutekey}/locations`)
.snapshotChanges()
.pipe(
map((locations) =>
locations.map(
(location) =>
({
key: location.payload.key,
...(location.payload.val() as {}),
} as unknown as Location)
)
)
);
}
And this is my component code
routeLocations: any[];
constructor(private firebase: FirebaseService) { }
ngOnInit(): void {
this.firebase.getTodaysRoute().subscribe((value) => {
this.routeLocations = value;
});
}
2
Answers
After 2 weeks of trying just about everything this was the solution:
}
This is the expected behavior, as
on
(like most modern cloud APIs) is an asynchronous operation.One way to handle this is to nest the second query inside the
on
callback of the first one:You won’t be able to return the
Observable
in that case though. I recommend looking into usingonce
(instead ofon
) and checking outasync
/await
for that.