ManuelDeLeon / viewmodel

MVVM for Meteor
https://viewmodel.org
MIT License
205 stars 23 forks source link

Converting a ReactiveArray to Array results in an empty Array #294

Closed arggh closed 7 years ago

arggh commented 7 years ago

I bumped into a strange situation, where I have a simple ViewModel which is basically storing values in an array property. When calling .array() on the ReactiveArray, I just get an empty array.

I managed to isolate it to a simple reproduction: https://github.com/arggh/reactivearray-issue

Also, I'm thinking some of the scenarios where an array should reactively update, don't actually cause an update, such as:

values: [],

doSomething() {
  const array = this.values().array();
  array[0] = 'Foobar';
  this.values(array);
}

I'm running Meteor 1.5.2.

ManuelDeLeon commented 7 years ago

Use this.values.value;

On Sep 12, 2017 6:18 AM, "arggh" notifications@github.com wrote:

I bumped into a strange situation, where I have a simple ViewModel which is basically storing values in an array property. When calling .array() on the ReactiveArray, I just get an empty array.

I managed to isolate it to a simple reproduction: https://github.com/arggh/reactivearray-issue

Also, I'm thinking some of the scenarios where an array should reactively update, don't actually cause an update, such as:

doSomething() { const array = this.values().array(); array[0] = 'Foobar'; this.values(array); }

I'm running Meteor 1.5.2.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ManuelDeLeon/viewmodel/issues/294, or mute the thread https://github.com/notifications/unsubscribe-auth/AED31pimpap0Ni0Lbrlw2Ll_NlapM0T9ks5shnZrgaJpZM4PUjgr .

arggh commented 7 years ago

Am I missing something, isn't this still a defect? I thought whenever I call .array() on a ReactiveArray I'm supposed to get the contents as a plain Array, but in the reproduction, I just get an empty array?

ManuelDeLeon commented 7 years ago

This one took me a while to figure out. The problem is with the line:

this.values()[index] = value;

ReactiveArray isn't really an array, it's an object which behaves like one. When you assign a value directly by the index, and the reactive array object doesn't have an entry on that index, JS treats the index as the name of the property. Once that happens the state of the reactive array gets messed up. At that point the length is 0, slicing it yields an empty array, and who knows what else happens.

There is no other solution but to use .push to add new items to the array.