.set missing?

#9 · closed · 21 comments

View on GitHub ↗

dotnetwise

Since `ReactiveArray` is like `ReactiveVar` should have the standard methods of `ReactiveVar` e.g. `get`, `set`, `dep`, `curValue` etc.

Comments

ManuelDeLeon

Not really. ReactiveArray is different from ReactiveVar in that it keeps track of the collection, not the individual items in the array. In other words you'll get notified (so to speak) if an element is added or removed from the array, not if an item changed.

dotnetwise

Indeed, but I don't understand how to set the content of the `ReactiveArray` with another computed (raw) `array` value at all. Of course, I can do `.splice(0, 0)` and then add items one by one, but seems tidious e.g. a pollyfill until you'll implement the counter-part set could be: ``` js ReactiveArray.prototype.set = ReactiveArray.prototype.set || function (newArrayValuesToSet) { this.length && this.splice(0, this.length); if (newArrayValuesToSet && newArrayValuesToSet.length) { this.push.apply(this, newArrayValuesToSet); } return this; //to allow chaining }; ```

ManuelDeLeon

ReactiveArray is meant to mirror an Array object as closely as possible without adding extra helpers. You should be able to work with a ReactiveArray just like you would with a normal array but get reactivity out of it. That way you can use your preferred library to deal with arrays (sugar, underscore, linq2js, etc.) If you're asking how to add an array to an existing one the answer is "the same way you would do it with a normal array". ``` js array1.push.apply(array1, array2) ```

dotnetwise

I completely agree with you, but still, there is no way to get rid of the old values and push new ones, unless you do the ugly code as you showed. ``` js reactiveArray1.splice(0, reactiveArray1.length); reactiveArray1.push.apply(reactiveArray1, array2) ``` I want simply to `change` its value with another array and not write boggy code ``` js reactiveArray1.set(array2) ``` Does it make sense now?

ManuelDeLeon

> I want simply to change its value with another array An array doesn't contain "a value" but a collection of values. How would you do it with a plain Array while still maintaining a reference to the original one? Exercise: ``` js var original = [1,2,3]; var originalRef = original; var newValues = [4,5,6]; // Change original so it has the new values but still keeps the original reference. console.log("Original as the same reference: " + (original === originalRef)); ```

dotnetwise

Why are you still saying about the reference - no one said that. I simply want to remove all of the current values and push new ones. Isn't that already obvious from all of my above code examples? But again, in a simple `.set` operation and not in an ugly `splice` & `push` as above

ManuelDeLeon

Because you have to keep the reference to the original reactive array to get notified that the contents of the array changed. Otherwise it would be a different reactive array with different dependencies. So how would you change the contents of a plain Array?

dotnetwise

I don't get it. I am planning to run a query and later when `minimongo` will provide the data (e.g after. `subscriptionReady`) (or data changes e.g. in an `template.autorun` deps tracker) I want to push the values in a `ReactiveVar`. But obviously that won't work with `{{#each}}` block, so I need to put the values in a `ReactiveArray` instead. When the query will change, perhaps it will replace the whole content of the `ReactiveArray` anyways. Can your `ReactiveArray` be initialized with a coursor that will monitor reactively over the time?

ManuelDeLeon

I think you're going about it the wrong way. Cursors are already reactive so you don't need to dump their contents into an array. Just return the results of the cursor in the helper that feeds `#each`

dotnetwise

That's correct, but at the time the template binds, I don't have the cursors ready.

ManuelDeLeon

It doesn't matter, the cursor's result will trigger a change when it's ready.

dotnetwise

It works as you said, but still I think this would be a good functionality. Btw, in `BLAZE` if you're using a helper twice or more times, it will be computed every single time, although you're referring to the same query/data. Using `ReactiveArray` you could manually optimize this where performance is critical.

ManuelDeLeon

> in BLAZE if you're using a helper twice or more times, it will be computed every single time What do you mean "it will be computed every single time"? If you use an array it will have to pull the values from the array the same way it would have to pull the values from the minimongo cache. If you're using a heavy transformation in multiple places you can do it inside an autorun that updates an array and then have the helper(s) return the values from the array.

dotnetwise

Exactly! So for that case setting the new values after recomputed in the `autorun` I need the `.set(newArrayWithValues)` feature I am asking for in the first place.

ManuelDeLeon

> I need the .set(newArrayWithValues) feature I am asking for in the first place. And I keep asking how would you do it with a normal array.

ManuelDeLeon

Again, the purpose of this library is to mirror a regular array and let you work with it the same way you work with regular array. That way you can use whatever helper library you want (sugar, underscore, lodash, linq2js, or nothing at all). So however you do it with a plain array, you should be able to do it with ReactiveArray.

dotnetwise

Dude, I understand that. But what if you add an extra method that is already in `ReactiveVar` anyway? Would it do any harm to whom??

ManuelDeLeon

There are many methods I would love to add that make my life easier (and probably others as well) but for every person that is happy to have a built in helper, there will be another that won't be because they already have it with library X that they use.

dotnetwise

Pfff. That's called communism as opposite to open source community collaboration.

ManuelDeLeon

whatever

derwaldgeist

> If you're asking how to add an array to an existing one the answer is "the same way you would do it with a normal array". > ```array1.push.apply(array1, array2)``` It would be useful if that was mentioned in the docs. I was fearing that doing this would cause the reactive autoruns to be run for each single element, so I was looking for a way to add a whole array without causing this. BTW: I noticed that helpers depending on the array via `array()` run *twice*, if I call `apply()` (on 20 elements in my case). There is no other reactive variable in the helper, and also no other external cause why the helper should be called more than one time. How can I avoid this?