Borislav Hadzhiev
Tue Mar 15 2022·2 min read
Photo by Drew Coffman
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
.
Here are 3 examples of how the error occurs.
// 👇️ 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.
// 👇️ 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.
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:
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
.