Reputation: 357
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>
Upvotes: 0
Views: 163
Reputation: 1643
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');
}
}
Upvotes: 1
Reputation: 2879
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>
Upvotes: 0