[Fixed] How to loop through an object only once in the view (single *ngFor)?

Issue

I have this object and each property has an array as its value. I would like to loop through this object only once instead of using 2 *ngFor directives because it causes slowness to my app. I’m also open to create an array out of this object but I still would like to add a section id for each section as shown in the example below. Can anyone point me in the right direction? Thanks a a lot in advance! Here’s my code.

LIVE DEMO

<div *ngFor="let group of dataObject | keyvalue">
    {{group.key}}
    <div *ngFor="let item of group.value; let i=index;">
        {{item.name}}
    </div>
</div>

NOTE: My final goal is to wrap each person into a section where they belong and add an id to each of those sections.
Example:

  <div id = "parentId"> 
     <div id = "section-a">
        list of all users that belong in section a
     </div>
     <div id = "section-b">
         list of all users that belong in section b
     </div>
     <div id = "section-c">
         list of all users that belong in section c
     </div>
 
    <div>
    ......
    ......
  </div>

Solution

You may generate a new property reduced and use this new property

In your component

dataObject = {
    A: [
        {id: 1, name: 'Mike', lastname: 'asmith'},
        {id: 2, name: 'Mary', lastname: 'alters'},
        {id: 3, name: 'Boris', lastname: 'al'}
    ],
    B: [
        {id: 1, name: 'Lauren', lastname: 'bmith'},
        {id: 2, name: 'Travis', lastname: 'balters'},
        {id: 3, name: 'Barn', lastname: 'bl'}
    ], 
    ...
}
dataObjectDisp = Object.entries(this.dataObject).reduce((prev, [key, value]) =>{
  return [...prev, ...value.map((user, index) => ({ 
    ...user, parent: key, index }))]
}, [])

The above code will reduce the structure to

[
  {
    "id": 1,
    "name": "Mike",
    "lastname": "asmith",
    "parent": "A",
    "index": 0
  },
  {
    "id": 2,
    "name": "Mary",
    "lastname": "alters",
    "parent": "A",
    "index": 1
  },
  ...
]

Now we have a way to identify when the a new section starts. Its index will be zero

To display the html you can do something like below

<h1>New</h1>
<div *ngFor="let item of dataObjectDisp; let i = index" [attr.data-article]='"section" + item.parent'>
  <ng-container *ngIf="item.index === 0">
    {{ item.parent }}
  </ng-container>
  <div>
    {{item.lastname}}
  </div>
</div>

Note the attribute [attr.data-article]='"section" + item.parent'. This can be used to identify different sections

Leave a Reply

(*) Required, Your email will not be published