Home > Blockchain >  How to display the information of a subobject using ngfor
How to display the information of a subobject using ngfor

Time:02-04

I am developing an application with angular and I need to display some data that has the following structure:

{
    "id": 33,
    "arg": 7,
    "date": "2022-01-31",
    "User": {
        "Name": "Cristian",
        "Group": {
            "NGroup": "Group 1"
        }
    },
    "Sport": {
        "NSport": "Sport 1"
    }
},

The information should be displayed in this way

id | arg | date | Name (User) | NGroup (Group) | NSport (Sport)

For this I was trying to use keyvalue, the problem with this is that when it brings the User object, it shows me an "item" called [object Object] that corresponds to group and there is no way to hide it. This is the current code:

                 <tbody>
                    <tr *ngFor="let item of listItems">
                      <td><div>{{ item.id }}</div></td>                               
                      <td><div>{{ item.arg}}</div></td>
                      <td><div>{{ item.date }}</div></td>
                      <td *ngFor="let key of item.User | keyvalue "><div>{{ key.value }}</div></td>
                      <td *ngFor="let key of item.User | keyvalue"><div *ngFor="let key2 of key.value | keyvalue" >{{ key2.value }}</div></td>                         
                      <td *ngFor="let kv of item.Sports | keyvalue"><div>{{kv.value}}</div></td>                         
                   
                    </tr>  
                  </tbody>

The output of this is:

id | arg | date | [Object,Object] | Name(User) | NGroup (Group) | NSport(sport)

The question is : How could I show only some items of the object and not all the content

Thanks!!

CodePudding user response:

You can filter out the items to display using something like this:

<table>
 <tr *ngFor="let item of listItems">
 <td><div>{{ item.id }}</div></td>                               
 <td><div>{{ item.arg}}</div></td>
 <td><div>{{ item.date }}</div></td>
 <ng-container *ngFor="let key of item.User | keyvalue ">
  <td *ngIf="isInteresting(key.value)">{{ key.value }}</td>
 </ng-container>

 <td *ngFor="let key of item.User | keyvalue"><div *ngFor="let key2 of 
key.value | keyvalue" >{{ key2.value }}</div></td>                         
 <td *ngFor="let kv of item.Sport | keyvalue"><div>{{kv.value}}</div></td>                         

</tr>  
</table>

and in the component:

isInteresting(val): boolean { return typeof val !== 'object'; }

CodePudding user response:

This may be dodging the question, but typically I try to keep component template files simple. It helps keep business logic contained inside your TS file which also enables for better testing scenarios.

Since you know the desired output id | arg | date | Name (User) | NGroup (Group) | NSport (Sport) you should use the component's TS file to create that interface for the view. A simple .map() should do the job.

this.viewItems = this.listItems.map(item=>{
  const { id, arg, date, User, Sport } = item;
  const name = User.Name;
  const nGroup = User.Group.NGroup;
  const nSport = Sport.NSport;
  return { id, arg, date, name, nGroup, nSport };
});

Now you only need one *ngFor loop for rendering your data.

<tbody>
  <tr *ngFor="let item of viewItems">
    <td><div>{{ item.id }}</div></td>
    <td><div>{{ item.arg}}</div></td>
    <td><div>{{ item.date }}</div></td>
    <td><div>{{ key.name }}</div></td>
    <td><div>{{ key.nGroup }}</div></td>
    <td><div>{{ key.nSport }}</div></td>
  </tr>
</tbody>

Note: While it's already defined in your source data, I would avoid naming objects with uppercase letters (User and Sport). This naming style should be reserved for defining classes.

  •  Tags:  
  • Related