Use the built-in keyvalue
-pipe like this:
<div *ngFor="let item of myObject | keyvalue">
Key: <b>{{item.key}}</b> and Value: <b>{{item.value}}</b>
</div>
or like this:
<div *ngFor="let item of myObject | keyvalue:mySortingFunction">
Key: <b>{{item.key}}</b> and Value: <b>{{item.value}}</b>
</div>
where mySortingFunction
is in your .ts
file, for example:
mySortingFunction = (a, b) => {
return a.key > b.key ? -1 : 1;
}
Stackblitz: https://stackblitz.com/edit/angular-iterate-key-value
You won't need to register this in any module, since Angular pipes work out of the box in any template.
It also works for Javascript-Maps.
It appears they do not want to support the syntax from ng1.
According to Miško Hevery (reference):
Maps have no orders in keys and hence they iteration is unpredictable. This was supported in ng1, but we think it was a mistake and will not be supported in NG2
The plan is to have a mapToIterable pipe
<div *ngFor"var item of map | mapToIterable">
So in order to iterate over your object you will need to use a "pipe". Currently there is no pipe implemented that does that.
As a workaround, here is a small example that iterates over the keys:
Component:
import {Component} from 'angular2/core';
@Component({
selector: 'component',
templateUrl: `
<ul>
<li *ngFor="#key of keys();">{{key}}:{{myDict[key]}}</li>
</ul>
`
})
export class Home {
myDict : Dictionary;
constructor() {
this.myDict = {'key1':'value1','key2':'value2'};
}
keys() : Array<string> {
return Object.keys(this.myDict);
}
}
interface Dictionary {
[ index: string ]: string
}
try to use this pipe
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'values', pure: false })
export class ValuesPipe implements PipeTransform {
transform(value: any, args: any[] = null): any {
return Object.keys(value).map(key => value[key]);
}
}
<div *ngFor="#value of object | values"> </div>
Updated : Angular is now providing the pipe for lopping through the json Object via keyvalue
:
<div *ngFor="let item of myDict | keyvalue">
{{item.key}}:{{item.value}}
</div>
WORKING DEMO , and for more detail Read
Previously (For Older Version) : Till now the best / shortest answer I found is ( Without any Pipe Filter or Custom function from Component Side )
Component side :
objectKeys = Object.keys;
Template side :
<div *ngFor='let key of objectKeys(jsonObj)'>
Key: {{key}}
<div *ngFor='let obj of jsonObj[key]'>
{{ obj.title }}
{{ obj.desc }}
</div>
</div>
WORKING DEMO
In addition to @obscur's answer, here is an example of how you can access both the key
and value
from the @View.
Pipe:
@Pipe({
name: 'keyValueFilter'
})
export class keyValueFilterPipe {
transform(value: any, args: any[] = null): any {
return Object.keys(value).map(function(key) {
let pair = {};
let k = 'key';
let v = 'value'
pair[k] = key;
pair[v] = value[key];
return pair;
});
}
}
View:
<li *ngFor="let u of myObject |
keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li>
So if the object were to look like:
myObject = {
Daario: Naharis,
Victarion: Greyjoy,
Quentyn: Ball
}
The generated outcome would be:
First name: Daario
Last Name: Naharis
First name: Victarion
Last Name: Greyjoy
First name: Quentyn
Last Name: Ball
Adding to SimonHawesome's excellent answer. I've made an succinct version which utilizes some of the new typescript features. I realize that SimonHawesome's version is intentionally verbose as to explain the underlying details. I've also added an early-out check so that the pipe works for falsy values. E.g., if the map is null
.
Note that using a iterator transform (as done here) can be more efficient since we do not need to allocate memory for a temporary array (as done in some of the other answers).
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'mapToIterable'
})
export class MapToIterable implements PipeTransform {
transform(map: { [key: string]: any }, ...parameters: any[]) {
if (!map)
return undefined;
return Object.keys(map)
.map((key) => ({ 'key': key, 'value': map[key] }));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With