TypeError: Cannot add property 1, object is not extensible↵ at Array.push (<anonymous>)
I am trying to add some data to an array but I am getting not extensible error.
Component code:
this._store.select(p => p.collection.workspaceCollectionPages).subscribe((data: CollectionPageDbModel[]) =>{
if(data){
return data.map((collectionPageDbModel)=> {
this.collectionPages.push(collectionPageDbModel) //Getting error on this line while pushing
});}
I have four objects in my data var, which I am trying to push in collectionPages, but I am getting extensible error while pushing.
collectionPage array where i need to add more data
This data I need to push
CollectionPageDbModel:
export class CollectionPageDbModel implements IDbModel {
public id?: number;
public collection_version_id: number;
public user_id?: string;
public name: string;
public position?: number = 0;
public contents: string;
public created_at?: string;
public updated_at?: string;
public server_id?: any;
}
Can someone please help me out resolving this
Solution 1:
Make a copy of object using the Object.assign method and try again,
this.collectionPages = Object.assign([], this.collectionPages);
this.collectionPages.push(collectionPageDbModel);
Solution 2:
The solution proposed by Daniel certainly works for this case. The reason is Object Descriptors which every JS object have. You can check them out by calling Object.getOwnPropertyDescriptors(obj)
and it will work for arrays too since (almost) everything is an object.
NGRX Store Selectors that were most probably used in the question modify object descriptors by using Object.defineProperties(obj)
. That is done to prevent any mutation of the data in the Store outside of the Reducer (which doesn't mutate state either, just creates a new one).
In general case you have to clone the object that you want to mutate:
import { cloneDeep } from 'lodash'
// ...
constructor(private store: Store<any>) {}
someMethod() {
let someDataFromTheStore = cloneDeep(this.store.select(selectSomeData))
someDataFromTheStore.myArray.push('...')
}
Both Object.assign
and cloneDeep
don't transfer descriptors to the new copy.
Object.getOwnPropertyDescriptors
Object.defineProperties