Reputation: 39374
I have the following on an Angular 7 application:
<ng-container *ngIf="(post$ | async) as post; else loader">
<div *ngIf="post; else empty">
Post content
</div>
</ng-container>
<ng-template #empty>
Post not found
</ng-template>
<ng-template #loader>
Loading post
</ng-template>
This works fine when post is defined ...
However when post
is undefined the "Post not Found" does not show ...
... I just see the Loading message which does not disappears.
What am I missing?
Update
post$ is defined as follows in the component:
Note: post$ is not an array. See envelope.result[0] in the code.
export class PostDetailComponent implements OnInit {
@Input() postId: number;
post$: Observable<PostDetailModel>;
constructor(private postService: PostService) { }
ngOnInit() {
this.post$ = this.getPost();
}
getPost(): Observable<PostDetailModel> {
return this.postService.getByPostId(this.postId).pipe(
map((envelope: Envelope<GetByPostIdResponse>) => envelope.result[0]),
map((response: GetByPostIdResponse) => {
return response == null ? null : {
id: response.id,
title: response.title
// other properties
};
}));
}
Upvotes: 0
Views: 5877
Reputation: 62213
post
is evaluated as truthy/falsy already in the initial ng-container
. If post
resolves to undefined
then the ng-template #loader
will display. Your current logic will never display ng-template #empty
. I would recommend you use map
to change the returned value if it is undefined
and then check that in your subsequent *ngIf
.
component
export class AppComponent implements OnInit {
post$: Observable<any>;
ngOnInit(){
this.post$ = of(undefined).pipe(
delay(2000),
map(_ => typeof _ === 'undefined' ? 'NotFound' : _)
);
}
}
template
<ng-container *ngIf="(post$ | async) as post; else loader">
<div *ngIf="post !== 'NotFound'; else empty">
Post content
</div>
</ng-container>
<ng-template #empty>
Post not found
</ng-template>
<ng-template #loader>
Loading post
</ng-template>
Upvotes: 3
Reputation: 1997
I think its always undefined. Undefined while its waiting, and also undefined or maybe null when it returns in that state. I think the best way to to be more explicit about whats going on:
ts
loading = false;
post;
getPost() {
this.loading = true;
this.postService.getPost().subscribe(post => {
this.loading = false;
this.post = post;
});
}
html
<ng-container *ngIf="!loading; else loader">
<div *ngIf="post; else empty">
Post content
</div>
</ng-container>
<ng-template #empty>
Post not found
</ng-template>
<ng-template #loader>
Loading post
</ng-template>
this way you aren't trying to infer the state of the post from which kind of falsey it might be
Upvotes: 0
Reputation: 8478
you can use !!
to check for valid values. You can see explanation of !!
here
<ng-container *ngIf="(post$ | async) as post; else loader">
<div *ngIf="!!post; else empty">
Post content
</div>
</ng-container>
<ng-template #empty>
Post not found
</ng-template>
<ng-template #loader>
Loading post
</ng-template>
Upvotes: 1