'TypeError: Cannot assign to read only property | after creating a copy
I wan't to copy an array (that is stored in my Redux Toolkit store), re-assign some properties and return it back.
I noticed that it works like this:
const copy = JSON.parse(JSON.stringify(options));
copy[0].last = true;
But I wan't to do it like this but it throws an error:
const copy = [...options];
copy[0].last = true;
This error is thrown:
Uncaught TypeError: Cannot assign to read only property 'last' of object '#'
Why is JSON.stringify and JSON.parse needed here to make it work?
The options are defined like this:
interface Options {
label: string;
first: boolean;
last: boolean;
}
const options: Options[];
Solution 1:[1]
It's impossible to tell exactly what's going on, because the nature of your options array is unknown. However, the difference between your first and second code sample is that the JSON routines read the options element values and then construct a completely new array, without all the details of writability from the original options values. In the second case, you've made a shallow copy of options, so the element objects are the same objects as in the original array. If a property isn't writable in the original, it won't be writable in your shallow copy.
edit — in response to your edit, some code somewhere is creating an object in the array such that the last property is not writable. I don't know exactly how or why, but it's easily possible to do that, either via Object.freeze() (which makes all the properties unwritable) or with Object.defineProperty() and the appropriate flag value for one of the properties.
Thus:
- something populates your array
- for whatever reason, some or all properties of some or all of the objects in the array are marked as non-writable
- you make a shallow copy of the array, which brings over references to the exact same objects that are found in the original array
- the properties are still not writable
In the original JSON version, the writability flags are not preserved in the to/from JSON transformation. (Note that transforming objects as JSON is not guaranteed to work in all cases, including many typical and common cases, because JSON serialization can only handle a small subset of JavaScript object possibilities.)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
