I've been learning TypeScript with Angular. And currently I stuck as this moment. Previously I used subscribed method and everything works flawlessly, but not I decided to rewrite the code using async pipe and it just does't work....
export interface responseFormat {
success: boolean;
data: any;
}
export interface restaurant {
_id: string;
name: string;
description: string;
images: file[];
cuisines: cuisine[];
blocked: boolean;
created: Date;
business_hours: object;
}
/* Provider */
getRestaurant(): Observable<responseFormat> {
return this.http.get<responseFormat>(environment.api + "/restaurant");
}
/* Component */
private restaurant: restaurant;
getRestaurant() {
this.restaurantProvider.getRestaurant().subscribe(res => {
if (res.success) this.restaurant = res.data;
});
}
as a result the type of the variable is assigned.... But I don't want to keep the record of subscriptions thus I wanted to convert the code using Angular async pipe... This is what I've done... it doesn't works
/* Provider */
getRestaurant(): Observable<responseFormat> {
return this.http.get<responseFormat>(environment.api + "/restaurant");
}
/* Component */
private restaurantObservable: Observable<restaurant>;
getRestaurant() {
this.restaurantObservable = this.restaurantProvider.getRestaurant().map(res => <restaurant>res.data);
// or //
this.restaurantObservable = this.restaurantProvider.getRestaurant().map(res => res.data as restaurant);
}
But the above code doesn't cast the type of the response to the interface...
What am I doing wrong???
In other words I can get the Observable variables in template (with https://angular.io/api/common/AsyncPipe> like that:
/* Provider */
getRestaurant(): Observable<responseFormat> {
return this.http.get<responseFormat>(environment.api + "/restaurant");
}
/* Component */
private restaurantObservable: Observable<restaurant>;
getRestaurant() {
this.restaurantObservable = this.restaurantProvider.getRestaurant().map(res => res.data as restaurant);
}
/* Template */
<div class="name">{{ (restaurantObservable | async)?.name }}</div>
// or //
<div *ngIf="restaurantObservable | async as restaurant">
<div>{{ restaurant.name }}</div>
</div>
But I can't get the property of the restaurant observable in component... For instance this.restaurant.cuisines throw the error "property cuisines does not exist on type Observable"
Why not directly return an Observable<restaurant>
from your service?
getRestaurant(): Observable<restaurant> {
return this.http.get<responseFormat>(environment.api + "/restaurant")
.map((response: responseFormat) => response.data as restaurant);
}
Then on component side:
getRestaurant() {
this.restaurantProvider.getRestaurant().subscribe((res: restaurant) => {
this.restaurant = res;
});
}
The error handling (success
flag, HTTP errors, etc) could be handled via an HTTP Interceptor.
The Angular async template pipe subscribes to the Observable, that is how it is able to access the restaurant object and its properties in the template.
If you want to access to these same thing in the component controller then you need to make a subscription in the component controller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With