Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot add property X, object is not extensible after ngrx 9 update

I am having an issue like

Cannot add property X, object is not extensible

after updating my angular project to angular 9 with Ngrx update as well. When I rollback Ngrxversion to 8 it's working fine. But I need to update that as well to v9 with angular 9 updates. This has happened when I add this as datasource.data in the material table with additional attribute. I think that additional attribute alteration is a reason for that. But I create new array from what we got and tried out like below by using slice.

 myDataArray.slice(0)

It also not working.

I refer change list of Ngrx version 8 to 9 and migration guideline here https://ngrx.io/guide/migration/v9

As I found there is a special change related to immutability with angular 9. They have defined Action, state and serializability related immutability logic there. And I tried out the method that they have suggested to resolve those issues with Ngrx V9 update here https://ngrx.io/guide/store/configuration/runtime-checks

But those are not worked for me. It's really helpful if anyone has a solution to this issue. Thanks in advance..

error stack trace.. (I used matDataFlatner as well that's where the object mutation happens)

app-error-handler.ts:30 TypeError: Cannot add property level, object is not extensible at MatTreeFlattener.defaultFlattenerTransform [as transformFunction] (tree-table-flattener-builder.ts:57) at MatTreeFlattener._flattenNode (flat-data-source.ts:58) at flat-data-source.ts:81 at Array.forEach () at MatTreeFlattener._flattenChildren (flat-data-source.ts:78) at MatTreeFlattener._flattenNode (flat-data-source.ts:65) at flat-data-source.ts:92 at Array.forEach () at MatTreeFlattener.flattenNodes (flat-data-source.ts:92) at MatTreeFlatDataSource.set (flat-data-source.ts:138)

like image 672
PushpikaWan Avatar asked Mar 27 '20 09:03

PushpikaWan


2 Answers

You should deep-clone myDataArray because it's coming out from the store through a selector. Keeping the immutability of the data in the store is an important part of redux pattern and you'd be changing the data directly in the store if you modify myDataArray (depending on your selector, it could be the same data => a reference to the array in the store).

You can do myDataArray = JSON.parse(JSON.stringify(myDataArray)) before trying to make any change in it.

There are more efficient ways of deep-cloning an object, for example using fast-copy:

import copy from 'fast-copy';

...

myDataArray = copy(myDataArray);
like image 68
julianobrasil Avatar answered Oct 27 '22 09:10

julianobrasil


You can use cloneDeep function from lodash library to deep clone the object and avoid the error:

import {cloneDeep} from 'lodash';

const clonedData = cloneDeep(myDataArray);

Then, you can add properties or all that you want to clonedData object.

Regards!

like image 32
Amn Avatar answered Oct 27 '22 11:10

Amn