109

I want to iterate [object object] using *ngFor in Angular 2.

The problem is the object is not array of object but object of object which contains further objects.

{

  "data": {
    "id": 834,
    "first_name": "GS",
    "last_name": "Shahid",
    "phone": "03215110224",
    "role": null,
    "email": "[email protected]",
    "picture": **{ <-- I want to get thumb: url but not able to fetch that**
      "url": null,
      "thumb": {
        "url": null
      }
    },
    "address": "Nishtar Colony",
    "city_id": 2,
    "provider": "email",
    "uid": "[email protected]"
  }
}

I know we can use pipe to iterate the object but how we can iterate further from object to object means data->picture->thum:url.

7
  • 1
    Dup of stackoverflow.com/questions/37046138/… Commented Dec 30, 2016 at 12:49
  • You're perhaps lookin for recursive functions. Commented Dec 30, 2016 at 12:58
  • I don't see any difficulty here, if you have array of objects, you can itterate with ngFor easily Commented Dec 30, 2016 at 13:25
  • @Umar : Could you please put two of them so we could have a bigger picture ? Commented Dec 30, 2016 at 13:26
  • @Milad that is not array of object, that is the main problem. that is whole packed object, which contain further object like data->picture->thumb->url . i want to access the thumb0->url Commented Jan 3, 2017 at 6:47

10 Answers 10

210

Angular 6.0.0

https://github.com/angular/angular/blob/master/CHANGELOG.md#610-2018-07-25

introduced a KeyValuePipe

See also https://angular.io/api/common/KeyValuePipe

@Component({
  selector: 'keyvalue-pipe',
  template: `<span>
    <p>Object</p>
    <div *ngFor="let item of object | keyvalue">
      {{item.key}}:{{item.value}}
    </div>
    <p>Map</p>
    <div *ngFor="let item of map | keyvalue">
      {{item.key}}:{{item.value}}
    </div>
  </span>`
})
export class KeyValuePipeComponent {
  object: {[key: number]: string} = {2: 'foo', 1: 'bar'};
  map = new Map([[2, 'foo'], [1, 'bar']]);
}

original

You can use a pipe

@Pipe({ name: 'keys',  pure: false })
export class KeysPipe implements PipeTransform {
    transform(value: any, args: any[] = null): any {
        return Object.keys(value)//.map(key => value[key]);
    }
}
<div *ngFor="let key of objs | keys">

See also How to iterate object keys using *ngFor?

Sign up to request clarification or add additional context in comments.

12 Comments

thanks for reply! by this approach now i can access the picture->url but not picture->thumb->url. how to further iterate into it .. <div *ngFor="let key of posts | objs"> <ion-avatar item-left *ngIf="key=='picture'"> <img [src]="posts[key].url"> <-- picture url here want thumb url which is futher into picture object </ion-avatar> </div>
Sorry, I don't understand what the comment is about. Why can't you access picture->thumb->url? Perhaps [src]="posts[key].thumb.url"?
You're welcome. Glad to hear you could make it work.
i have an other json response, i am using the same approach as above but getting error, Cannot convert undefined or null to object. here is a json response. { "id": 1, "food": "McDonalds Sharebox Chicken Plus (Drink - Coke)", "user_id": 834, "rating_id": null, "runner_id": 43, }
It was added 6.1.0
|
59

I think the most elegant way to do that is to use the javascript Object.keys like this (I had first implemented a pipe for that but for me, it just complicated my work unnecessary):

in the Component pass Object to template:

Object = Object;

then in the template:

<div *ngFor="let key of Object.keys(objs)">
   my key: {{key}}
   my object {{objs[key] | json}} <!-- hier I could use ngFor again with Object.keys(objs[key]) -->
</div>

If you have a lot of subobjects you should create a component that will print the object for you. By printing the values and keys as you want and on an subobject calling itselfe recursively.

Hier you can find an stackblitz demo for both methods.

2 Comments

Not sure if this is the ideal way! But it works. Seems like an optimal solution for my requirement.
This is perfect! I've been looking for this for the past 30 minutes! Works exactly as expected on an object like this: [nosings: {a : 1, b: 2}, communal_carpets: {a:1, b:2, c:3}]
17

I know this question is already answered but I have one solution for this same.

You can also use Object.keys() inside of *ngFor to get required result.

I have created a demo on stackblitz. I hope this will help/guide to you/others.

CODE SNIPPET

HTML Code

<div *ngFor="let key of Object.keys(myObj)">
  <p>Key-> {{key}} and value is -> {{myObj[key]}}</p>
</div>

.ts file code

Object = Object;

myObj = {
    "id": 834,
    "first_name": "GS",
    "last_name": "Shahid",
    "phone": "1234567890",
    "role": null,
    "email": "[email protected]",
    "picture": {
        "url": null,
        "thumb": {
            "url": null
        }
    },
    "address": "XYZ Colony",
    "city_id": 2,
    "provider": "email",
    "uid": "[email protected]"
}

2 Comments

15

Looping through object in Angular HTML templates

keyValuePipe is introduced in Angular: Please refer https://angular.io/api/common/KeyValuePipe

Quick code:

<p>Object</p>
    <div *ngFor="let item of object | keyvalue">
      {{item.key}}:{{item.value}}
    </div>
    <p>Map</p>
    <div *ngFor="let item of map | keyvalue">
      {{item.key}}:{{item.value}}
    </div>

Comments

12

You have to create custom pipe.

import { Injectable, Pipe } from '@angular/core';
@Pipe({
   name: 'keyobject'
})
@Injectable()
export class Keyobject {

transform(value, args:string[]):any {
    let keys = [];
    for (let key in value) {
        keys.push({key: key, value: value[key]});
    }
    return keys;
}}

And then use it in your *ngFor

*ngFor="let item of data | keyobject"

1 Comment

i have done with that, the problem is ngFor use with array of object, in my case that is not array of object, object into object then further object into object like this data->picture->thumb->url .
5

1.Create a custom pipe to get keys.

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

@Pipe({
  name: 'keys'
})
export class KeysPipe implements PipeTransform {

  transform(value: any, args?: any): any {
    return Object.keys(value);
  }
}
  1. In angular template file, you can use *ngFor and iterate over your object object
<div class ="test" *ngFor="let key of Obj | keys">
    {{key}}
    {{Obj[key].property}
<div>

Comments

2

Angular now has a type of iterate Object for exactly this scenario, called a Set. It fit my needs when I found this question searching. You create the set, "add" to it like you'd "push" to an array, and drop it in an ngFor just like an array. No pipes or anything.

this.myObjList = new Set();

...

this.myObjList.add(obj);

...

<ul>
   <li *ngFor="let object of myObjList">
     {{object}}
   </li>
</ul>

1 Comment

What type do you use for myObjList? When I tried it, my linter says: Type 'Set<any>' is not assignable to type 'IMyInterface'
0

If you are using a map() operator on your response,you could maybe chain a toArray() operator to it...then you should be able to iterate through newly created array...at least that worked for me :)

1 Comment

object does not use toArray
0

After doing a lot of troubleshooting nested loops in the template, I found that this worked better for my use:

(For one thing I was trying to iterate agm-polygon and it wouldn't let me nest divs).

In component.ts:

Object = Object

values= Object.values(this.arrayOfObjects)

In component.html:

<div *ngFor='let value of values'>{{value.property}}</div>

Once you retrieve the values, you do have an Iterable, and do not need to worry about also iterating through the keys in the template, which can get complex and look messy.

Comments

-9

i would do this:

<li *ngFor="let item of data" (click)='onclick(item)'>{{item.picture.url}}</li>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.