How to Display Json Object Using *Ngfor

I want to display the below data from Firebase

{
   "-KBN9O_qqz-nZ9tPWFdM":{
      "createdAt":1456399292790,
      "isActive":true,
      "name":"Hero 1"
   },
   "-KBN9gjJw1ZlMgt9pVsl":{
      "createdAt":1456399371220,
      "isActive":true,
      "name":"Hero 2"
   },
   "-KBN9hYI4vYAsyh5k1lX":{
      "createdAt":1456399374548,
      "isActive":true,
      "name":"Hero 3"
   }
}

when doing angular.io Tour of Heroes tutorial for example

<li *ngFor="#hero of heroes">
  <span class="badge">{{hero.id}}</span> {{hero.name}}
</li>

So hero id should show for example -KBN9hYI4vYAsyh5k1lX and hero name should show for example hero 3


I have done some research and come across this stackoverflow solution by @Thierry Templier access key and value of object using *ngFor

(1) Is this the right solution to my problem?

(2) Is there a simpler solution to this problem because I feel that it would be really common for developers using Angular2 to display such json data.

2

4 Answers

You need to implement a custom pipe to do this. ngFor only supports array and not object.

This pipe will look like that:

@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
  transform(value, args:string[]) : any {
    let keys = [];
    for (let key in value) {
      keys.push({key: key, value: value[key]});
    }
    return keys;
  }
}

and use it like that:

<span *ngFor="#entry of content | keys">           
  Key: {{entry.key}}, value: {{entry.value}}
</span>

See this question for more details:

5

You can put the keys in an array and ng-repeat the keys.

export class IterateOverObject {
    public arrayOfKeys;

    @Input heros;
    constructor() {
        this.arrayOfKeys = Object.keys(this.heros);
    }
}

<li *ngFor="#key of arrayOfKeys">
  <span class="badge">{{key}}</span> {{heros[key].name}}
</li>

This looks simple to me.. More info is here

1

Firebase id is called $.key. Also, # is now changed to let. This would work for you:

<li *ngFor="let hero of heroes">
  <span class="badge">{{hero.$key}}</span> {{hero.name}}
</li>

Angular did support KeyValuePipe from version 6.1

@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']]);
}

More info:

Your Answer

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

Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest