4 Leave Cover
4 Leave Cover

Reputation: 1276

nested loop error when displaying in html after retrieve from API

I am new to ionic 3 and angular. Basically I wanted to create a list with header (data from MySQL database through PHP API). The header will display the category while the items will go to ion-item section.

However when I try to call the 2nd ngFor it throws me error as shown below in the picture. I notice a lot people use GET method while I am using POST method which are harder to find solution out there. Please enlighten, thanks in advance.

JSON

enter image description here

home.ts

this.storage.get('username').then((val) => {
  let headers: any = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
    options: any = { "username": val },
    url: any = "path_to_my_api";

  this.http.post(url, options, headers)
    .subscribe((data: any) => {
      this.prods = data.products;
    },
      (error: any) => {
        console.log(error);
      });
});

home.html

<ion-list *ngFor="let prod of prods | async">
    <ion-list-header>
      {{prod.category}}
    </ion-list-header>
    <ion-item *ngFor="let myitem of prod.item | async">
        <ion-avatar item-start>

        </ion-avatar>
        <h2>haha{{myitem.code}}</h2>
      </ion-item>
  </ion-list>

Upvotes: 1

Views: 230

Answers (1)

Ben Steward
Ben Steward

Reputation: 2417

Try this

Logic:

this.http.post(url, options, headers)
  .subscribe((data: any) => {
    const categoryMap = data.products.reduce((categories, prod) => {
      if (categories[prod.category]) {
        categories[prod.category].push(prod);
      } else {
        categories[prod.category] = [prod];
      }

      return categories;
    }, {});

    this.categories = Object.keys(categoryMap).map(category => ({
      category,
      products: categoryMap[category]
    });
  }, (error: any) => {
    console.log(error);
  });

Template:

<ion-list *ngFor="let cat of categories | async">
  <ion-list-header>
    {{cat.category}}
  </ion-list-header>
  <ion-item *ngFor="let prod of cat.products | async"> <!-- not sure if async pipe is necessary here though -->
    <ion-avatar item-start></ion-avatar>
    <h2>haha{{prod.item.code}}</h2>
  </ion-item>
</ion-list>

To clarify, the final structure of your data will look like this:

this.categories = [
  {
    category: "Beer Bottles",
    products: [
      {
        item: {code: 'whatever'},
        category: "Beer Bottles"
      },
      {
        item: {code: 'something else'},
        category: "Beer Bottles"
      },
      ...etc.
    ]
  },
  {
    category: "Beer Draught",
    products: [ ...relevant products as above]
  }
]

Upvotes: 2

Related Questions