Cannot assign to read only property of Object in JavaScript

avatar

Borislav Hadzhiev

Tue Mar 15 20222 min read

banner

Photo by Drew Coffman

Cannot assign to read only property of Object in JavaScript #

The error "Cannot assign to read only property of object" occurs when we try to change a property of an object that has been frozen or when a property has been defined with Object.defineProperties(). To solve the error, create a copy of the object or array, or set the property to writable.

cannot assign to read only property error

Here are 3 examples of how the error occurs.

index.js
// 👇️ With OBJECTS 👇️ const obj = { name: 'James', }; Object.freeze(obj); // ⛔️ Error: Cannot assign to read // only property 'name' of object '#<Object>' obj.name = 'Alice'; // 👇️ With ARRAYS 👇️ const arr = ['a', 'b', 'c']; Object.freeze(arr); // ⛔️ Error: Cannot assign to read // only property '0' of object '[object Array]' arr[0] = 'z'; // 👇️ with Object.defineProperties() 👇️ const obj2 = {}; Object.defineProperties(obj2, { country: { value: 'Germany', // 👉️ must be set writable: true // writable: true, // 👈️ uncomment this }, }); // ⛔️ Error: Cannot assign to read // only property 'country' of object '#<Object>' obj2.country = 'Austria';

The first two errors occur because the object or array has been frozen with the Object.freeze() method. A frozen object can no longer be changed, but you can create a copy of the array or object and change the copy.

index.js
// 👇️ With OBJECTS 👇️ const obj = { name: 'James', }; Object.freeze(obj); const objCopy = {...obj}; // 👈️ create copy objCopy.name = 'Alice'; console.log(objCopy); // 👉️ {name: 'Alice'} // 👇️ With ARRAYS 👇️ const arr = ['a', 'b', 'c']; Object.freeze(arr); const arrCopy = [...arr]; // 👈️ create copy arrCopy[0] = 'z'; console.log(arrCopy); // 👉️ ['z', 'b', 'c']

We used the spread syntax (...) to create a copy of the object and array, so we can change them.

If you are getting the error when using the Object.defineProperties method, you have to set the property as writable if you want to change its value.

index.js
const obj2 = {}; Object.defineProperties(obj2, { country: { value: 'Germany', writable: true, }, }); obj2.country = 'Austria'; console.log(obj2.country); // 👉️ "Austria"

The country property is set to writable, so it can be changed.

The writable parameter defaults to false when using the Object.defineProperties() method, so if you want to be able to change the value of a property, explicitly set writable to true.

If you pass an object or array to Object.freeze, you can't:

  • add new properties or elements to it
  • remove existing properties
  • change existing properties

The best way to get around this is create a copy of the object or array and change the copy.

If you are using some third-party library which has frozen a state object or array, chances are you aren't supposed to be mutating the state object directly. The library probably exports a method that should be used to change the state.

Use the search field on my Home Page to filter through my more than 1,000 articles.