Skip to content
Advertisement

Iterating through a an array executing a switch statement returns TypeError: Cannot assign to read only property ‘location’ of object ‘#’

I have a read only array that i copied to become a mutable array let mutableForecast = [...forecast] I am taking that new array and iterating through it with forEach so i can mutate the array. im trying to use some flow control with a switch statement, but I am getting TypeError: Cannot assign to read only property 'location' of object '#<Object>'

JavaScript

Whats the issue here? I’ve look at this, this, this and some others but cannot find an answer.

This is what the forecast array looks like before i copied it enter image description here

Advertisement

Answer

It’s hard to be sure without knowing where forecast comes from, but I suspect the problem is that the elements of the array are not plain objects, but instances of a custom type that are defined as immutable. Your third link has the likely solution. The key is that you can’t convert an array of immutables into an array of mutables simply by using rest & spread in this way. You need to modify the mutability of each item in the array individually.

You probably need something like this:

JavaScript

This might also work, and I think it’s cleaner. You’d have to try it to be sure:

JavaScript

The core problem we’re working around is that whatever package gives you forecast, it clearly trafficks in some custom datatype, some of whose properties are defined as immutable. That fact doesn’t show up when you log the objects, and it isn’t changed when you convert an array-like container into an array.

That’s because [...forecast] doesn’t edit the items, it just copies them as-is from one data structure into another. Actually, be to precise, it copies references to those objects into a new array. If the original objects are weird things with locked properties, then your new array will consist of weird things with locked properties. If we want to change the value of that property on each element, we need to redefine the property before doing so.

Consider a case like this:

JavaScript

We can create another object with the same properties like so:

JavaScript

If the same property names occurs twice, the engine will only honor the last one:

JavaScript

So, we can override individual object properties while copying by re-declaring those properties last:

JavaScript

That’s what is going on in that second snippet. Here’s an expanded version:

JavaScript
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement