I have Angular + Firebase app. In one of my components i get elements from Firebase DB and binding them into template with *ngFor:
<div *ngFor="let comment of (comments | async)>
<div>{{ comment.text }}</div>
</div>
But every comment
also have answers
list:
How can i bind answers inside my loop, for example, something like this:
<div *ngFor="let comment of (comments | async)>
<div>{{ comment.text }}</div>
<div *ngFor="let answer of comment.answers">
{{ answer.text }}
</div
</div>
This structure does not work and return error:
Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
You must convert it into an array, before displaying it in your *ngFor loop. If you want to keep the key, you can merge it into the object in the map call as well.
You can't use multiple *ngFor s in the same element as those are structural directives and angular handles them in a specific way (basically for each structural directive it creates an ng-template element which then holds the directive itself, you can read more about it here: https://angular.io/guide/structural- ...
In *ngFor the * is a shorthand for using the new angular template syntax with a template tag, this is also called structural Directive.It is helpful to know that * is just a shorthand to explicitly defining the data bindings on a template tag.
*ngFor is a predefined directive in Angular. It accepts an array to iterate data over atemplate to replicate the template with different data. It's the same as the forEach() method in JavaScript, which also iterates over an array.
The answers property is an object. You must convert it into an array, before displaying it in your *ngFor
loop.
component.html
<div *ngFor="let comment of (comments | async)>
<div>{{ comment.text }}</div>
<div *ngFor="let answer of toArray(comment.answers)">
{{ answer.text }}
</div
</div>
component.ts
export class Component {
toArray(answers: object) {
return Object.keys(answers).map(key => answers[key])
}
}
If you want to keep the key, you can merge it into the object in the map call as well.
export class Component {
toArray(answers: object) {
return Object.keys(answers).map(key => ({
key,
...answers[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