Search code examples
angularfirebasefirebase-realtime-databaseobservableangularfire

Firebase .equalto function resolve before executing rest of the code


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;
    });
  }

Solution

  • After 2 weeks of trying just about everything this was the solution:

    async getTodaysRoute(): Promise<Observable<Location[]>> {
    const date = new Date().toISOString().replace(/\T.*/, '');
    const userdate = `${this.useremail}${date}`;
    let todaysroutekey;
    await this.db.database
      .ref()
      .child('routes')
      .orderByChild('user_date')
      .equalTo(userdate)
      .once('child_added', function (snapshot) {
        todaysroutekey = snapshot.key;
      });
    
    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)
          )
        )
      );
    

    }

    this.firebase.getTodaysRoute().then(
      (event) =>
        event.subscribe(
          (value: any) =>
            (this.routeLocations = value.sort((a, b) => a.id - b.id))
        )
    );