Reputation: 109
I'm trying to subscribe to an Observable so I can display it in HTML with Angular, doing console.log(player)
works fine however I get
Type 'Player' is missing the following properties from type 'Observable<Player>': _isScalar, source, operator, lift, and 6 more.ts(2740)
I've tried using .pipe()
,
HTML:
<div *ngIf="(player$ | async) as player">
<div *ngIf="player.characterUid">
{{player.characterName}}
</div>
</div>
Component:
player$: Observable<Player>;
subPlayer: Subscription;
selectPlayer(matEvent: MatAutocompleteSelectedEvent): void {
this.inputFriends = matEvent.option.value;
this.selectedPlayer = matEvent.option.value;
this.inputP = false;
this.subPlayer = this.playerProvider.get$(matEvent.option.value.userUid).subscribe(
(player: Player) => {
this.player$ = player; // Type 'Player' is missing the following properties from type 'Observable<Player>': _isScalar, source, operator, lift, and 6 more.ts(2740)
}
);
}
Provider:
get$(uid: string): Observable<Player> {
return this._getDoc(uid)
.valueChanges()
.pipe(
map((sPlayer: ServerPlayer) => sPlayer ? new Player(sPlayer) : null)
);
}
private _getDoc(uid: string): AngularFirestoreDocument {
return this.afs.doc(`players/${uid}`);
}
I'm just trying to assign player$
so I can display it in the HTML
Upvotes: 2
Views: 1272
Reputation: 24406
you don't need to subscribe , async pipe will subscribe and get the value for you 🧙♂️
player$: Observable<Player>;
selectPlayer(matEvent: MatAutocompleteSelectedEvent): void {
this.inputFriends = matEvent.option.value;
this.selectedPlayer = matEvent.option.value;
this.inputP = false;
this.player$= this.playerProvider.get$(matEvent.option.value.userUid);
}
The async pipe takes care of subscribing and unwrapping the data as well as unsubscribing when the component is destroyed, so you don't need subPlayer
template
<ng-container *ngIf="(player$ | async) as player">
<div *ngIf="player.characterUid">
{{player.characterName}}
</div>
</ng-container>
Upvotes: 2
Reputation: 1481
I'm just trying to assign player$ so I can display it in the HTML
this.player$ = this.playerProvider.get$(matEvent.option.value.userUid);
this method returns an observable, so if you want to assign player$
, you can do it that way. In your html template, you're using | async
which handles subscribe/unsubscribe automagically.
Upvotes: 1
Reputation: 4062
In your code player$
is not an observable, it's already the result of the observable.
player: Player; // <-- here
subPlayer: Subscription;
selectPlayer(matEvent: MatAutocompleteSelectedEvent): void {
this.inputFriends = matEvent.option.value;
this.selectedPlayer = matEvent.option.value;
this.inputP = false;
this.subPlayer = this.playerProvider.get$(matEvent.option.value.userUid).subscribe(
(player: Player) => {
this.player = player; // <-- here
}
);
}
<div *ngIf="player"> <!-- here -->
<div *ngIf="player.characterUid">
{{player.characterName}}
</div>
</div>
Upvotes: 1