Update nested prop in immerjs causes "Cannot assign to read only property" exception

Viewed 245

I'm trying to update a nested prop on one of my objects, which according to the docs should work exactly like that, I believe. Just the be clear the state has a list of lessons, each lesson has a list of modules and the module in question has a property I'm trying to set.

on(setBootstrapScript, (state, action) => {
    return produce(state, (draft) => {
      const index = draft.lessons[action.lessonId].modules.findIndex(
        (module) => module.uuid === action.moduleId,
      );
      if (index !== -1) {
        draft.lessons[action.lessonId].modules[
          index
        ].bootstrapScript = action.bootstrapScript;
      }
    });
  })

Note: I know there are utilities like ngrx-etc or ngrx-immer which have mutableOn functions but that's not the issue here. It should still work like this.

It works fine when using it in a test like this

test('setBootstrapScript should set the correct database bootstrap script', async () => {
    let results = reducer(
      initialState,
      setBootstrapScript({
        lessonId: 0,
        moduleId: 1,
        bootstrapScript: 'CREATE NEW TABLE;',
      }),
    );
    expect(results.lessons[0].modules[0]).toEqual(
      expect.objectContaining({
        bootstrapScript: 'CREATE NEW TABLE;',
      }),
    );
  });

but using it in the browser results in a

core.js:6210 ERROR TypeError: Cannot assign to read only property 'bootstrapScript' of object '[object Object]'

I'm not sure what exactly I'm doing wrong, since immer should allow me to update the state like this. It works fine in production since immer turns off the autofreeze. For some reason the modules (or property of the modules) are set to writable false.

Any pointers would be appreciated, thanks.

0 Answers
Related