Angular Wait for boolean function to finish
Asked Answered
O

2

5

I am trying to fetch a list of users from my firestore database, and determine if the logged in user is an admin (i.e. he's in the list).

This is my code:

isAdmin(user: any): boolean {
    var col = this.afs.collection('admins');
    var docRef = col.doc('mini-admins');
    docRef.ref.get().then(function (doc) {
      if (doc.data().user == user)
        return true;
    }).catch(function (error) {
      console.log("Error getting document:", error);
    });
    return false;
}

However, even though the user is an admin, the function doesn't work. It looks like it isn't waiting for it to finish before proceeding.

How do I fix this?

Osugi answered 11/2, 2018 at 15:49 Comment(0)
W
5

.then indicates ref.get is an async function. You can't wait for async functions. You can only return the Promise returned from it or a new one that is properly chained, and pass another callback on the callers site to execute code when the promise completes:

isAdmin(user: any): Promise<boolean> {
    var col = this.afs.collection('admins');
    var docRef = col.doc('mini-admins');
    // vvv added return
    return docRef.ref.get().then(function (doc) {
      return doc.data().user == user;
    }).catch(function (error) {
      console.log("Error getting document:", error);
    });
}

and then use it like

this.isAdmin(user).then(response => {
  if(response) {
    ...
  } else {
    ...
  }
});
Whiz answered 11/2, 2018 at 15:54 Comment(5)
Gives me an error: 'Property 'then' does not exist on type 'boolean'.'Osugi
Error: "Type 'Promise<boolean | void>' is not assignable to type 'boolean'."Osugi
Sorry, missed to fix the return type - updated againCamisole
Type 'Promise<boolean | void>' is not assignable to type 'Promise<boolean>'. Type 'boolean | void' is not assignable to type 'boolean'. Type 'void' is not assignable to type 'boolean'.Osugi
Can you please try adding return false; after console.log... in you .catch( block and tell me if the error goes away?Camisole
C
11

It's not working because it's asynchronous. To make it work you need to change it slightly to:

isAdmin(user: any): Observable<boolean> {
    return new Observable(observer => { 
       var col = this.afs.collection('admins');
       var docRef = col.doc('mini-admins');
       docRef.ref.get().then(function (doc) {
          if (doc.data().user == user) {
              observer.next(true);
              observer.complete();
          }   
       }).catch(function (error) {
          observer.error(error);
          observer.complete();
          console.log("Error getting document:", error);
       });
    });
}

Then in your code when you want to check if the user is admin, call this function in the following way:

this.isAdmin(user).subscribe(success => { ... }, error => { ... });
Croix answered 11/2, 2018 at 15:57 Comment(2)
Sorry for discarding your edit to my answer. You were right but I didn't see it at first.Camisole
No problem, that's fine :)Croix
W
5

.then indicates ref.get is an async function. You can't wait for async functions. You can only return the Promise returned from it or a new one that is properly chained, and pass another callback on the callers site to execute code when the promise completes:

isAdmin(user: any): Promise<boolean> {
    var col = this.afs.collection('admins');
    var docRef = col.doc('mini-admins');
    // vvv added return
    return docRef.ref.get().then(function (doc) {
      return doc.data().user == user;
    }).catch(function (error) {
      console.log("Error getting document:", error);
    });
}

and then use it like

this.isAdmin(user).then(response => {
  if(response) {
    ...
  } else {
    ...
  }
});
Whiz answered 11/2, 2018 at 15:54 Comment(5)
Gives me an error: 'Property 'then' does not exist on type 'boolean'.'Osugi
Error: "Type 'Promise<boolean | void>' is not assignable to type 'boolean'."Osugi
Sorry, missed to fix the return type - updated againCamisole
Type 'Promise<boolean | void>' is not assignable to type 'Promise<boolean>'. Type 'boolean | void' is not assignable to type 'boolean'. Type 'void' is not assignable to type 'boolean'.Osugi
Can you please try adding return false; after console.log... in you .catch( block and tell me if the error goes away?Camisole

© 2022 - 2024 — McMap. All rights reserved.