Search code examples
ngrxngrx-store

Observable from store.select doesn't seem to have updated values


I have an ApplicationState which has project member and my ProjectState is something like this:

interface ProjectState {
   listObjs: SomeType[];
}

In my component.ts onInit I have something like this:

...
this.objID = someString
...

this.listObj$ = 
this.store.select( state => state.project.listObjs.find( item => item.id === this.objID));
...

In my reducer I am handling creation of new state like this:

...
case (action.ACTION1): {

    const newState = {... state};
    const objIndex = state.listObjs.findIndex( item => item.id === action.payload.id )

    if ( objIndex === -1 ) {
        return state;
    }

    Object.assign(newState.listObjs[objIndex].someMember, {... action.payload.someData});

    return newState;
}
...

I subscribed to listObj$ in my component onInit, but it gets served when initializing and whenever I make changes to obj in array I don't see the subscribe getting updated data


Solution

  • This is "direct" state mutation.

    The spread operator (...) does not clone recursive and Object.assign mutates newState.listObjs[objIndex].someMember.

    You can install ngrx-store-freeze or enable the runtime checks in ngrx v8, and you'll get an error that you can't modify the state like this.

    To solve this issue, you'll have to create a new state in an immutable way, or use immer. Clean NgRx reducers using Immer