ObservableArray mutates


#1

When I run this.dataItems.map on a radlist view, it actually mutates the dataItems which is an observable array. It seems odd to me that map would mutate the ObservableArray. That isn’t how Observables work in Rx or javascript. map returns a new list in those contexts.

Is there a way for me to make a copy of an ObservableArray to iterate over it without mutating it?


#2

Do you mean it map triggers change event though your UI reloads?


#3

Well, the ui isn’t reloading, but if I console.log out the array it has changed at the end of the map routine. I’m doing a quiz type of interface, where you have to drag the items into order. After they are done, they can submit and I run some checks to see if the order is correct. I set classes on the items that are correct and incorrect. Then they can click another button to reorder the items in the way the should be. A bit complex, but essentially, I need to modify the list using data in the code behind. My classes are getting applied within the code without me even updating the dataitems observable array. I thought I was returning an array that was correct, and then I would update the observable, but it is updating as I do my code routines using .map() and .push(), even though I thought I was mapping and pushing to external arrays.


#4

Map should not mutate, if you can prepare a Playground example it is easy to confirm if thats a bug.


#5

I’ve created one, but it is hard to see the ObservableArray since the console doesn’t seem to allow for console.log of the array. However, if you drag the items into place and then hit submit, you will see that the items get updated classes and turn either green or red depending on correct or incorrect. It doesn’t seem to me like it should work that way as I am mapping over the dataItems Obsrvable and setting the class on a completely different array.


#6

I can confirm it works as expected, map is not mutating but you are mutating the array within your map function. Remember Object is passed by reference and not by value, every item in the Observable array is an object and you are updating the same object then adding it to your new array. The arrays are different but the items inside are same, to avoid this behavior you must clone the object before using it.


#7

How do you clone the object? Also, how do you reset an ObservableArray? Do I do this?

this.dataItems = new ObservableArray(items);


#8

You can do something like this,

const clonedItem = {
 ...item
};