Reputation: 976
I'm having problems in this situation:
@Component({
selector: 'my-app',
template: `
{{items | async| json}}
<div *ngFor="let item of items | async">
<input type=checkbox [(ngModel)]="item.b"/>
</div>
`
})
export class AppComponent {
items = of([{
name: '1',
},
{
name: '2',
},
{
name: '3',
}])
.pipe(map(i=>{
return i.map(i=>{
return {
i: i,
b: false
}
})
}))
}
The problem is that the ngModel is not working and I can't see the b property change. If I remove the map pipe and I put the boolean property in the first array, all is working. Am I missing something? What's the problem?
Thanks
Upvotes: 1
Views: 669
Reputation: 38807
You're not doing anything wrong. If you render out {{item.b}}
in the ngFor
you will see the value is changing between true
and false
correctly. As mentioned in the other answer this is because of references and change detection. You can also simply save the observable data a property on your class using ngOnInit
and subscribe
:
import { Component } from "@angular/core";
import { of } from "rxjs";
import { map } from "rxjs/operators";
@Component({
selector: "my-app",
template: `
{{ items | json }}
<form #myForm="ngForm">
<div *ngFor="let item of items">
<input [name]="item.i.name" type="checkbox" [(ngModel)]="item.b" />
</div>
</form>
`
})
export class AppComponent {
items: any[] = [];
ngOnInit() {
this.getData().subscribe(data => (this.items = data));
}
private getData() {
return of([
{
name: "1"
},
{
name: "2"
},
{
name: "3"
}
]).pipe(
map(i => {
return i.map(i => {
return {
i: i,
b: false
};
});
})
);
}
}
Here is an example in action. Don't forget to clean up any observables if needed to avoid memory leaks.
Upvotes: 3
Reputation: 1227
Actually what you are doing is correct. To check what I mean change your code to this:
<input type=checkbox (change)="change(item)" [(ngModel)]="item.b"/>
change(item) {
console.log(item);
}
This is not reflecting on the dom because the items array is mapped to the same memory location and changing an element inside it won't cause a change detection in angular to trigger a display change.
Upvotes: 2