I am trying to iterate over the properties of an object using *ngFor but using in. When I try to do this
@Controller({
selector: 'sample-controller',
template: `
<ul>
<li *ngFor="let i in obj">
<b>{{i}}</b>: {{obj[i]}}
</li>
</ul>`
})
class SampleController {
obj = {a: 1, b: 2}
}
I get the error message:
Can't bind to 'ngForIn' since it isn't a known property of 'li'.
I have included FormsModule and BrowserModule in the imports section of the @NgModule for this component.
Is it possible to use ngForIn on li and if not is there an idiomatic alternative?
As AJT_82 mentioned in comment you can create special directive for such purposes. It will be based on NgForOf<T> directive:
interface NgForInChanges extends SimpleChanges {
ngForIn?: SimpleChange;
ngForOf?: SimpleChange;
}
@Directive({
selector: '[ngFor][ngForIn]'
})
export class NgForIn<T> extends NgForOf<T> implements OnChanges {
@Input() ngForIn: any;
ngOnChanges(changes: NgForInChanges): void {
if (changes.ngForIn) {
this.ngForOf = Object.keys(this.ngForIn) as Array<any>;
const change = changes.ngForIn;
const currentValue = Object.keys(change.currentValue);
const previousValue = change.previousValue ?
Object.keys(change.previousValue) : undefined;
changes.ngForOf = new SimpleChange(previousValue, currentValue, change.firstChange);
super.ngOnChanges(changes);
}
}
}
Plunker Example
The easiest approach would be to turn your object into an array using Object.values() and Object.keys(). Check out this plunker for an example.
If you want access to the keys as well as the value you can include an index in your *ngFor.
Template:
<ul>
<li *ngFor="let item of array; let index = index;">
<b>{{keys[index]}}</b> value: {{item}}, index: {{index}}
</li>
</ul>
Component TypeScript:
export class App {
obj = {a: 1, b: 2}
array = [];
keys = [];
constructor() {
}
ngOnInit() {
this.array = Object.values(this.obj);
this.keys = Object.keys(this.obj);
}
}
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