Reputation: 6697
I am using *ngFor to display values from an array:
[
{
id: 1,
name: 'item1'
},
{
id: 2,
name: 'item2'
}
]
html:
<div *ngFor="let item of (items$ | async); trackBy: trackById;">
// more html to display data
</div
ts:
items$: Observable<any>;
trackById = trackByProperty('id');
ngOnInit() {
this.items$ = this.store.pipe(select(selectors.itemsSelector));
}
trackByProperty<T = any>(property: keyof T) {
return (index: number, object: T) => object[property];
}
This works as intended, ngFor gets the correct and current values in the items$ array
My issue is that when I update the items$
array using ngrx
it doesn't seem to catch the new array and doesn't update the DOM
Heres the flow of data using ngrx
Dispatch action to the reducer, sending a new object to add to the array.
this.store.dispatch(new actions.UpdateArray(
{ id: 3, name: 'item3' }
)
);
Reducer picks up this action and updates the store state with the updated array (receives the new item and pushes it to the array).
case actions.UPDATE_ARRAY: {
const newItem = action.payload;
const items = state.items;
items.push(newItem);
return {
...state,
items
};
}
Selector updates.
I can confirm the state gets updated correctly when logging out the action.payload in the reducer.
Does anyone know why I'm not getting an updated array in the *ngFor
?
Forgot to mention, but I'm using changeDetection: ChangeDetectionStrategy.OnPush
as my change detection in my component
I found out that the DOM actually updates when you click on the component. I'd like it to update without having to do that.
Upvotes: 2
Views: 1222
Reputation: 1316
This might happen because NgRx selectors use Memoization which sometimes causes undesirable behavior.
Changing
case actions.UPDATE_ARRAY: {
const newItem = action.payload;
const items = state.items;
items.push(newItem);
return {
...state,
items
};
}
to
case actions.UPDATE_ARRAY: {
const newItem = action.payload;
const items = [...state.items, newItem]; // <-- creates new instance
return {
...state,
items
};
}
should solve the problem.
Upvotes: 1