Atchaya
Atchaya

Reputation: 35

Angular 4: How to get and display the multiple data using angular 4

I have a problem to get the data in angular.

HTML:

<div class='col-md-6'>
  <div class='side-panel' style="margin-bottom: 20px;">
    <div class='headTxt'>
      <h5 *ngFor="let items of menuList">{{items.txt}}</h5>
      <div *ngFor="let items of menuList">{{items.item}}</div>
    </div>
  </div>
</div>

Typescript:

export class FoodItemsComponent implements OnInit {
  menuList;
  constructor() {
    this.menuList = [
      {txt:'Briyani',item:"chicken briyani"},
      {txt:'Indian veg rice'},
      {txt:'Rice & noodles'}, 
      {txt:'grill & shawarma'}, 
      {txt:'tandoori'}, 
      {txt:'chicken starter'}, 
      {txt:'egg dishes'},
      {txt:'Briyani'}, 
      {txt:'Briyani'},
    ];
   }

  ngOnInit() {
  }

}

I am trying to get this type of output:

1

But, am getting like this. Please, help.

2

Thanks in advance.

Upvotes: 1

Views: 559

Answers (2)

Suvethan Nantha
Suvethan Nantha

Reputation: 2454

You can achieve it by following below codes.

First of all create a custom pipe as shown below

import { Pipe } from '@angular/core';

@Pipe({name: 'groupBy'})
export class GroupByPipe implements PipeTransform {
  transform(value: Array<any>, field: string): Array<any> {
    const groupedObj = value.reduce((prev, cur)=> {
      if(!prev[cur[field]]) {
        prev[cur[field]] = [cur];
      } else {
        prev[cur[field]].push(cur);
      }
      return prev;
    }, {});
    return Object.keys(groupedObj).map(key => return { key, value: groupedObj[key] });
  }
}

Then add the following in your component where you have to inject the custom pipe previously created.

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <h2>Menu</h2>
      <div *ngFor="let menu of menuList | groupBy:'txt' ">
       <span style="font-weight: bold;">{{ menu.key }} </span> 
       <div *ngFor="let val of menu.value">{{ val }}</div>
      </div>
    </div>
  `,
  pipes: [GroupByPipe],
  directives: []
})

I have slightly modified the JSON array to support the format you mentioned in the question

this.menuList=[ {txt:'Briyani',item:"chicken briyani"},
      {txt:'Indian rice',item:"veg"},
      {txt:'Rice & noodles',item:"veg"}, 
      {txt:'grill & shawarma',item:"fish"}, 
      {txt:'tandoori',item:"chicken"}, 
      {txt:'starter',item:"chicken"}, 
      {txt:'dishes',item:"egg"},
      {txt:'Briyani',item:"mutton briyani"}, 
      {txt:'Briyani',item:"fish briyani"}];

if you have JSON like this

    this.menuList=[{
    "txt": "Briyani",
    "item": [{
        "type": "Chicken Briyani",
        "price": "180",
        "img": "assets/images/3.JPG"
    }, {
        "type": "Mutton Briyani",
        "price": "180",
        "img": "assets/images/3.JPG"
    }, {
        "type": "Prawn Briyani",
        "price": "180",
        "img": "assets/images/3.JPG"
    }]
}, {
    "txt": "Indian Rice",
    "item": [{
        "type": "Chicken Rice",
        "price": "180",
        "img": "assets/images/3.JPG"
    }, {
        "type": "Fish Rice",
        "price": "180",
        "img": "assets/images/3.JPG"
    }]
}];

then you can follow the code below to achieve your task.

<div *ngFor="let menu of menuList">
  <h5>{{menu.txt}}</h5>
  <div *ngFor="let it of menu.item">
    <span>{{it.type}}</span>
    <span>{{it.price}}</span>
  </div>
</div>

Plunker Example

I hope this will fix your problem. If any suggestions or doubts let me know. Thanks.

Upvotes: 2

ForestG
ForestG

Reputation: 18105

You have two *ngFor after each other, instead of embeding the second one in the first. Also, your second ngFor is wrong, if you want to iterate trough the items of a menulist element. Try this (I changed the names for better readability):

<div class='col-md-6'>
  <div class='side-panel' style="margin-bottom: 20px;">
    <div *ngFor="let entries of menuList" class='headTxt'>
      <h5>{{entries.txt}}</h5>
      <div *ngFor="let items of entries">{{items}}</div>
    </div>
  </div>
</div>

Upvotes: 0

Related Questions