5

I have the following Angular 7 component:

export class PostComponent implements OnInit {

  post$: Observable<PostModel>;

  constructor(private postService: PostService) { }

  ngOnInit() {

    this.post$ = postService.getPostById(25);

  }

}

On the component template I used the following:

<p>Title: {{post$.title}}</p>

Title shows empty and I think is because post$ is an Observable.

When using arrays, e.g. posts$: Observable<PostModel[]> I pass the observable to the template and it works fine using ngFor.

But how should I do it in this case?

Observable with an Array

When using an Observable of an array I have the following in the HTML template:

<div *ngIf="(posts$ | async)?.length > 0; else loading">
  <ng-container *ngFor="let post of posts$ | async">
    {{post.title}}
  </ng-container>
</div>
<ng-template #loading>
  Loading ...
</ng-template>

This allows me to show a loading message while loading.

Miguel Moura
  • 36,732
  • 85
  • 259
  • 481
  • Well what's the difference between what you're doing with `users$` (and `posts$`, for that matter) and what you're doing with `post$`? That should give a you a clue. This is covered in the [tutorial](https://angular.io/tutorial). – jonrsharpe Jan 14 '19 at 17:03
  • 1
    Obviously you should use the [AsyncPipe](https://angular.io/api/common/AsyncPipe). Note that every `async` you use subscribes to your Observable, so if your Observable comes from the `HttpClient` then a new http request will be made for every new subscribtion (use of `async` in your template). – frido Jan 14 '19 at 17:14
  • 1
    @fridoo To prevent a new http request I could use a wrapper, no? Something like: . No? – Miguel Moura Jan 14 '19 at 18:00
  • 2
    @MiguelMoura yes, that'll work. – frido Jan 14 '19 at 18:06

1 Answers1

9

You will have to use the async pipe as:

<p>Title: {{(post$ | async).title}}</p>
Nikos Tsokos
  • 3,226
  • 2
  • 34
  • 41