observable-membrane icon indicating copy to clipboard operation
observable-membrane copied to clipboard

Re-assigned array items gets transformed to proxies

Open ahmedkandel opened this issue 5 years ago • 1 comments

Description

When using array methods that re-assign indexes like (splice, shift, unshift, sort, reverse), According to the way they work e.g. unshift, The method will get() re-assigned items though the membrane which will return proxy whenever the item is observable.

As a result, the method will replace the original target items with proxies, which will contaminate the original target with proxies instead of values.

Steps to Reproduce

const membrane = new ObservableMembrane();

const o = {
    x: 2,
    y: [
        {z:1}
    ]
};

const p = membrane.getProxy(o);

for (let i = 0; i < p.y.length; i++) {
    console.log('1st loop - index:', i, o.y[i] === p.y[i])
}

p.y.push({z: 2});

for (let i = 0; i < p.y.length; i++) {
    console.log('2nd loop - index:', i, o.y[i] === p.y[i])
}

p.y.unshift({z: 0});

for (let i = 0; i < p.y.length; i++) {
    console.log('3rd loop - index:', i, o.y[i] === p.y[i])
}

Expected Results

on 3rd loop, the === should yield false because p is a proxy of o

Actual Results

on 3rd loop, the === yields true for re-assigned items with new index 1 and 2 because the re-assigned items are now proxies in the original target.

Possible Solution Will create a PR to fix this by checking if re-assigning observable value to array, Then unwrap the value to revert the unwanted get() proxy wrapping.

ahmedkandel avatar Mar 27 '20 12:03 ahmedkandel

Short Description

Adding or removing items to an array using push and pop will keep the original items as there are. While adding or removing using shift and unshift which will move items to different indexes will also "unexpectedly" transform those items to proxies.

ahmedkandel avatar Mar 27 '20 15:03 ahmedkandel