I'm displaying a list of tasks in a todo with an ngFor and a checkbox to toggle the task status. I'm using store from ngrx with the following state interface:
export interface State {
tasks: Task[];
index: { [_id: string]: Task };
};
That's the reducer which is in charge of updating the task when the status change:
case TaskActions.UPDATE_TASK_SUCCESS: {
const task = action.payload;
state.index[task._id] = Object.assign(state.index[task._id], task);
return state;
}
And here is the task component which take the task as @Input and has changeDetectionStrategy set to onPush:
import { Component, OnInit, Input, ChangeDetectionStrategy, DoCheck } from '@angular/core';
import {Store} from '@ngrx/store';
import { AppState } from '../../../../domain';
import { TaskActions } from '../../../../domain/actions';
@Component({
selector: 'task',
templateUrl: './task.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./_task.component.scss']
})
export class TaskComponent implements OnInit, DoCheck {
@Input() task;
constructor(
private store: Store<AppState>,
private TaskActions: TaskActions
) { }
ngOnInit() {
}
ngDoCheck() {
console.warn('Check');
}
public toggleTaskStatus(_task) {
var new_task = Object.assign({}, _task, {['status']: (_task.status == 'todo' ? 'done' : 'todo')});
this.store.dispatch(this.TaskActions.updateTask(new_task));
}
}
With this configuration, the first time I click on the checkbox the task inside the store gets updated, but the UI doesn't reflect any change. From the second time instead, the UI start toggling its status but not according the store state (when task status is 'todo' in the store, the UI is 'done'). Moreover, to get updated the UI doesn't wait for the success action in the reducer (the service is creating an observable with a slight timeout of 1 second).
When changeDetectionStrategy is set to default, everything seems working correctly, with the UI updating according to store state.
What am I doing wrong? Is regarding the immutability of the state or some issues inside the component?