0

I am currently working on a project that requires angular as a front end and firebase as a backend. However, when I was querying for a doc, I can't do something in a snapshot but can't seem to return anything.

this.afs.doc(`meals/${meal.id}`).collection('pending', ref => ref.where('uid', '==', this.authService.getUserID())).valueChanges().pipe(take(1)).subscribe(matchingRecs => {
  if(matchingRecs.length > 0) {
    return true;
  }
  else return false
})

I have this at the moment and it returns underfined but i know its true because the console log prints true

  • 1
    Does this answer your question? [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – John Montgomery Mar 30 '20 at 23:09

3 Answers3

0

try to include into pipe a map operator

pipe(map(matchingRecs => matchingRecs.length > 0))

then in subscribe u will get only boolean values. also you can't return something from subscribe, you need to write logic inside subscribe callback

0

You're returning something in the subscriber function and its not supposed to return anything. If you need to return something, you should subscribe on the variable that receives the return and use a map instead of a subscribe:

let result!: boolean = this.afs.doc(`meals/${meal.id}`)
  .collection('pending', ref => ref.where(
    'uid', '==', this.authService.getUserID())
  ).valueChanges().pipe(
    map(matchingRecs => !!matchingRecs.length),
    take(1)
  );

result.subscribe(console.log);

You can use a get instead of valueChanges to get a single value:

let result!: boolean = this.afs.doc(`meals/${meal.id}`)
  .collection('pending', ref => ref.where(
    'uid', '==', this.authService.getUserID())
  ).get().pipe(
    map((v: firestore.QuerySnapshot<firestore.DocumentData>) => !!v.docs.length)
  );

result.subscribe(console.log);
julianobrasil
  • 8,954
  • 2
  • 33
  • 55
0

I would attack a bit differently altogether, but building on your query the easiest change would be :

return this.afs.doc(`meals/${meal.id}`)
      .collection('pending', ref => ref.where('uid', '==', 
          this.authService.getUserID()))
      .valueChanges()
      .pipe(switchMap(docs => of(docs.length > 0)));

-- or --

return this.afs.doc(`meals/${meal.id}`)
      .collection('pending', ref => ref.where('uid', '==', 
          this.authService.getUserID()))
      .valueChanges()
      .pipe(map(docs => docs.length > 0));

-- or if you need to return a promise an observable --

async myFunc() : Promise<boolean> {
    const hasRecords = await this.afs.doc(`meals/${meal.id}`)
      .collection('pending', ref => ref.where('uid', '==', 
          this.authService.getUserID()))
      .valueChanges()
      .pipe(map(docs => docs.length > 0)).toPromise();

    return hasRecords;
}
Segev -CJ- Shmueli
  • 1,535
  • 14
  • 15