I am trying to introduce ngrx into a large legacy angular app (upgraded to Angular 11). The app has a giant model, that holds pretty much all of the data and cannot be adjusted as it is widely used in the company.
The idea was to put an instance of the model into the ngrx store and update relevant parts with the help of "immer" and "ngrx-immer".
My problem is, that updating parts of it results in the following errors
// in the reducer
dashboard.widgets.push(action.widget)
ERROR TypeError: Cannot add property 1, object is not extensible
at Array.push (<anonymous>)
at dashboard.reducer.ts:39
at ngrx-immer-shared.js:9
at produce (immer.esm.js:1)
at ngrx-immer-shared.js:9
at ngrx-store.js:1265
at combination (ngrx-store.js:242)
at ngrx-store.js:747
at ngrx-store.js:275
at computeNextEntry (ngrx-store-devtools.js:426)
I also tried
immerOn(DashboardActions.addWidgetToDashboard, (state, action) => {
const dashboard = state.dashboards.find(d => d.id === action.dashboardId)
if (dashboard) {
dashboard.widgets = [...dashboard.widgets, action.widget]
}
}),
ERROR TypeError: Cannot assign to read only property '_widgets' of object '[object Object]'
at DashboardModel.set (dashboard.model.js:54)
at DashboardModel.set (validation-properties.js:104)
at dashboard.reducer.ts:39
at ngrx-immer-shared.js:9
at produce (immer.esm.js:1)
at ngrx-immer-shared.js:9
at ngrx-store.js:1265
at ngrx-immer-shared.js:9
at produce (immer.esm.js:1)
at ngrx-immer-shared.js:9
The dashboard model has setters for its widget attribute and it is not readonly. According to https://immerjs.github.io/immer/update-patterns/#array-mutations this should work.
I know this structure isn't ideal but splitting the model up is not an option.
How can I update nested parts of my ngrx state? What am I doing wrong?
Edit:
The DashboardModel looks like this (removed irrelevant parts for simplicity)
export declare class DashboardModel extends SelectableVisuItemBaseModel {
private _widgets;
constructor(name?: string);
get widgets(): WidgetBase[];
set widgets(value: WidgetBase[]);
}
As you can see, it has an explicit setter for widgets. My editor thinks it is fine as well.