Angular Firestore display a button depending of a

2019-08-25 02:31发布

Requested behaviour:
Displaying a button in an Angular view depending on a returned boolean of an Angular Service which checks if a Firestore document exists

Current State
The Service checks the existence of the document successfully. It also updates the global variable in the if/else statement. I can call the function in the service and it logs the boolean value but it does not return it.

Issue
When I call the function from the component it always logs [object Promise] and I get a ts lint error: Type 'Promise<Boolean>' is not assignable to type 'boolean'.

How can I solve that? Do I have to convert the promise into a boolean or an Observable?

My Service:

export class ProfileFollowService {
    
    // global variable which should be updated
    followState: boolean;
    
    // checks if the document exist and returns a boolean
    async checkFollow(followingID: string, followerID: string): Promise<Boolean> {
    const followDoc =
    this.angularFirestore.collection(`users/${followingID}/following`).doc(followerID).ref;

    return followDoc.get().then((doc) => {
      if (doc.exists) {
          this.followState = true;
      } else {
          this.followState = false;
      }

      return this.followState;
    });
  }
  
  async callCheckFollow(followingID: string, followerID: string) {
  
    const result = await this.checkFollow(followingID, followerID);
    console.log(result); //logs true or false as requested
    return result;
  }

}

My Component class:

export class ServiceTestComponent implements OnInit {

  followState: boolean;
  
  constructor(private followService: ProfileFollowService) {

  // throws TS Lint error: Type 'Promise<Boolean>' is not assignable to type 'boolean'.
    this.followState = this.followService.callCheckFollow('someID', 'someID');
    
   // logs [object Promise], should log true or false
   ngOnInit() {console.log('followstate' + this.followState);}


}

My Component html:

<div *ngIf="followState === true">
  <p>hello Doc</p>
</div>

<div *ngIf="followState === false">
  <p>No doc</p>
</div>

2条回答
Emotional °昔
2楼-- · 2019-08-25 03:14

In component typescript you have property which is boolean and you are assigning it to Promise inside the constructor.

Move your code to ngOnInit add async keyword before that and before assigning followState use keyword await

export class ServiceTestComponent implements OnInit {

  followState: boolean;

  constructor(private followService: ProfileFollowService) { }

   // logs [object Promise], should log true or false
   async ngOnInit() {
     console.log('followstate' + this.followState);

     this.followState = await this.followService.callCheckFollow('someID', 'someID');
   }


}
查看更多
Summer. ? 凉城
3楼-- · 2019-08-25 03:16

A bit blind coding, but might this work?

In the service using Rxjs to verify if the object exist, and return an Observable of the result. With snapshot changes so that the value can change dynamicly:

public callCheckFollow(followingID: string, followerID: string): Observable<boolean> {
    return of(this.angularFirestore.collection('users/${followingID}/following').doc(followerID).snapshotChanges().take(1).do(d => d.payload.exists));
}

In the TS Component, just grab the observable from the service.

export class ServiceTestComponent implements OnInit {

  followState: Observable<boolean>;

  constructor(private followService: ProfileFollowService) {
     this.followState = this.followService.callCheckFollow('someID', 'someID');   
   }
}

And then in the html listen async for changes on the follow state.

<div *ngIf="(followState | async)">
  <p>hello Doc</p>
</div>

<div *ngIf="(!followState | async)">
  <p>No doc</p>
</div>
查看更多
登录 后发表回答