0
votes

I need to get only single item, so I used ngIf instead ngFor in template.

Template:

<div *ngIf="item | async">
    Id {{ item.id }}
    Number {{ item.number }}
</div>

Service:

get(id: number): Observable<Response> {
return this.http
  .get(`myApi/id`)
  .map(response => response.json());
}

Component:

export class DetailItemPage {
 private item: Observable<Object>;

 ngOnInit(){
  this.getItem(6994);
 }

getItem(id){
  this.itemProvider.get(id).subscribe(
     res => {
       this.item = res;
       console.log(this.item);
     });
  }

} 

In the console log I see the object correctly.

With that example, I get error:

InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'

But if I remove the async pipe, WORKS. I can see the item id and number. Why? What I am doing wrong?

PS: I used Angular 4.1.3

2

2 Answers

6
votes

The async pipe expects a Promise or Observable. In your case you add a normal Object. This is not what the pipe wants, and so it throws an error. You do not have to use the async pipe here.

You can however use it like this:

export class DetailItemPage {
   private item: Observable<Object>;

   ngOnInit(){
     this.getItem(6994);
   }

   getItem(id){
      this.item = this.itemProvider.get(id);
   }
} 

In this case the item is really an Observable, and your pipe will be very happy. Just know that using Observable<Object> as type definition for your field value does not guarantee that you will actually have an Observable<Object> in there. Because the http call returns with an any, the compiler still believes all is good in the hood, even though it really wasn't.

1
votes

the async pipe is for dealing with Promise and Observable objects, item is not an observable, but the data contained in the response as you assing item inside your subscribe callback.

that would work if you do this :

getItem(id){
  this.item=this.itemProvider.get(id);
}