Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 n - getting invalid argument [object Object] ... for pipe 'AsyncPipe'

I am getting an error trying to display he results of my service call. The html page has an ngFor with the | async. I can make the call, get the results, but receiving an error when trying to render the page. I know the variable need to be an Observable for the async to work. I am not sure what I am doing wrong and have tried several things. Any insight is appreciated.

Error Message: Invalid argument '[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]' for pipe 'AsyncPipe'

Variable Definition

  public products:Observable<Product[]>;

Call to Service

ngOnInit() {

    this.productService.load().subscribe(
      data => {
        // Set the products Array
        this.products = data['_embedded'].products;
      },
      error => console.log('Could not find product catalog.')
    );

}

Service Call

 load() {
    return this._http.get(`http://localhost:8000/products`).map(response => response.json());
  }

HTML

<tbody *ngFor="let product of products | async">
          <tr>
            <td>{{product.sku}}</td>
            <td>{{product.materialNumber}}</td>
            <td>{{product.price}}</td>
            <td>{{product.baseUom}}</td>
            <td>{{product.packageSize}}</td>
            <td>{{product.casePack}}</td>
            <td>{{product.weight}}</td>
            <td>{{product.height}}</td>
          </tr>
          </tbody>

Data From Call

Data From Call

like image 458
Don Avatar asked Jun 30 '16 11:06

Don


1 Answers

Async pipe needs an Observable rather then an Array.

In your case just try to remove async:

<tbody *ngFor="let product of products">

Also change variable definition:

public products:Array<Product> = [];

Explanation: array | async does subscribe by itself.

The code

this.productService.load().subscribe(
  data => {
    // Set the products Array
    this.products = data['_embedded'].products;
  },...

transforms an Observable to Array of Products

Update: This already works in async manner: since products is an empty array, ngFor doesn't run. When Observable gets a response and populates data into products, a change detection round takes place and goes through ngFor again (now populating products)

Another weird thing I've noticed (I could be wrong):

ngFor very like should be on tr:

<tbody>
   <tr *ngFor="let product of products | async">
   ...
   </tr>
</tbody>

In this case you'll have multiple rows and just one tbody

like image 88
Andrei Zhytkevich Avatar answered Nov 08 '22 05:11

Andrei Zhytkevich