How to loop through a dynamic JSON object in Angular2 + template

Issue

I am using Angular 2 +

in .ts, there is a JSon object return from a API call named as optionList[]

The structure of this object looks as below:

optionList=

{
   property-A: '', property-B: '',property-C: '',property-D:'',property-E: 'type1'
},
{
   property-A: '', property-B: '',property-C: '',property-D: '',property-E: 'type2'
},
{
   property-A: '', property-B: '',property-C: '',property-D: '',property-E: 'type1'
},
{
   property-A: '', property-B: '',property-C: '',property-D: '',property-E: 'type1'
},
{
   property-A: '', property-B: '',property-C: '',property-D: '',property-E: 'type3'
},
{
   property-A: '', property-B: '',property-C: '',property-D: '',property-E: 'type4'
},
{
   property-A: '', property-B: '',property-C: '',property-D: '',property-E: 'type3'
},
{
   property-A: '', property-B: '',property-C: '',property-D: '',property-E: 'type4'
},
{
   property-A: '', property-B: '',property-C: '',property-D: '',property-E: 'type4'
},
{
   property-A: '', property-B: '',property-C: '',property-D: '',property-E: 'type5'
},

In the .html, I want to display as the below:

type1

here display all the object have the same value (type1) of property-E

type2

here display all the object have the same value (type2) of property-E

type3

here display all the object have the same value (type3) of property-E

……….

what I have done is to use *ngFor to loop through unique value of property-E as below:

//unique-property-E-arr is an array contains all the unique value of property-E
<ng-container *ngFor="let property-E of unique-property-E-arr">

  {{property-E}}

  <ng-container *ngFor="let option of optionList">
   <div *ngIf="option.property-E === property-E">
      <!--display each object here -->
   </div>
  </ng-container>

</ng-container>

It works but it will loop through all the option to get the option that have the same value of property-E. For example if the optionList.length is 100, the loop happens for 100 X (unique value of property-E) times, which slows down my application.
Do I need to move this logic to ts and how. What is the best practice for a standard Angular application to solve this problem, leave all the logic in template or move to .ts?

Solution

The thing that is slowing down your application is the number of ngIf conditions because these conditions are rechecked after every change on the page. It means that if there are 100 elements in your array, 100 if conditions are being computed indefinitely while your are interacting with the application. I would recommend shifting some of your logic to ts file which will definitely speed up your application.
You can create another object which will have grouped optionsList in based on type. In your ts file:

//create an object to contain objects of each element
optionsListGroupedByType:any={
    type1:[],
    type2:[],
    type3:[],
    type4:[],
    type5:[],
};

//all unique types
uniqueTypes:string[]=["type1","type2","type3","type4","type5"]


//function which will group optionsList in optionsListGroupedByType based on type. Note: This should be called after optionList is returned from the service.
setOptionsListByType(){     
    for(let i=0;i<this.optionList.length;i++)
    {
        this.optionsListGroupedByType[this.optionList[i]["property-E"]].push(this.optionList[i]);    
    }
}

Then based on this, in your html file:

<ng-container *ngFor="let type of uniqueTypes">

    {{type}}

    <ng-container *ngFor="let obj of optionsListGroupedByType[type]">

            <!--display each object here -->
            {{obj['property-A']}}

    </ng-container>

</ng-container>

In this way, you will avoid 100 ngIf running multiple times and your application will run smoothly.

Answered By – Nabil Shahid

Answer Checked By – Pedro (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.