Mobx: Array properties should be sliced (for concat, destructuring, etc)

Created on 5 Oct 2016  路  3Comments  路  Source: mobxjs/mobx

Those 5 example cases should all have the same output, but the 2nd and 4th are currently different:

var regularList = [];
regularList = ["a"].concat(regularList);
regularList = ["b"].concat(regularList);
regularList = ["c"].concat(regularList);
regularList = ["d"].concat(regularList);
console.log(regularList);

var observableList = mobx.observable([]);
observableList = ["a"].concat(observableList);
observableList = ["b"].concat(observableList);
observableList = ["c"].concat(observableList);
observableList = ["d"].concat(observableList);
console.log(observableList);

var myObject = {
  someList: []
 };
myObject.someList = ["a"].concat(myObject.someList);
myObject.someList = ["b"].concat(myObject.someList);
myObject.someList = ["c"].concat(myObject.someList);
myObject.someList = ["d"].concat(myObject.someList);
console.log(myObject.someList);

var myObservableObject = mobx.observable({
  someList: []
 });
myObservableObject.someList = ["a"].concat(myObservableObject.someList);
myObservableObject.someList = ["b"].concat(myObservableObject.someList);
myObservableObject.someList = ["c"].concat(myObservableObject.someList);
myObservableObject.someList = ["d"].concat(myObservableObject.someList);
console.log(myObservableObject.someList);

var observableWithSlice = mobx.observable({
  someList: []
 });
observableWithSlice.someList = ["a"].concat(observableWithSlice.someList.slice());
observableWithSlice.someList = ["b"].concat(observableWithSlice.someList.slice());
observableWithSlice.someList = ["c"].concat(observableWithSlice.someList.slice());
observableWithSlice.someList = ["d"].concat(observableWithSlice.someList.slice());
console.log(observableWithSlice.someList);

Output:

["d","c","b","a"]
["d","c","b","a", []]
["d","c","b","a"]
["d",["c",["b",["a",[]]]]]
["d","c","b","a"]

@mweststrate pointed out on gitter:

@bb that looks like a bug indeed
https://github.com/mobxjs/mobx/blob/master/src/types/observablearray.ts#L264 is the source

EDIT: forgot mobx.observable([]) in initial version

The _2nd_ example was not using mobx.observable. Sorry for this copy'n'paste error. It's now fixed above. Please note that this brought up another difference for the empty observable array.

馃悰 bug

All 3 comments

After a few more thoughts and debug outputs, it looks to me that an array property of an observable object is not imitating array as good as observableArray does.

Some more differences between the 5 examples:

  • all but the 4th return true for Array.isArray(x) (but all return true for x instanceof Array)
  • browser/nodejs console.log output an array literal for all except the wrong one (which results in type t or ObservableArray {})
  • Object.keys output: ["0","1","2","3"]vs []
  • Object.getOwnPropertyNames output: ["0","1","2","3","length"] vs ["$mobx"]
  • native toString toString.call(x) returns [object Array] vs [object Object]

See https://jsfiddle.net/bock/0bpxtasx/ for executable test cases.

Don't see any bugs here.

  • 1st example: native arrays works ok
  • 2nd example: nativeArray.concat(observableArray) results in [observableArray] as far as Array.isArray(observableArray) === false
  • 3rd example: concating native array, same as 1st example.
  • 4th example: you get the same result as in 2nd example but after assigning [observableArray] to observable property, it is being automatically converted to ObservableArray so you get ObservableArray["a", observableArray], then ["b" ObservableArray["a", observableArray]] becomes ObservableArray["b", ObservableArray["a", observableArray]] and so on.
  • 5th example: you converting ObservableArray to Array before passing it to concat, so you get native array that, converted to ObservableArray after assining it to observable prop

What's wrong with that?

Thanks for analyzing @andykog!

Behavior in all cases seems to be correct. (Not per se desirable, but alas, proxies.... Safari hurry up!)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jamiewinder picture jamiewinder  路  4Comments

hellectronic picture hellectronic  路  3Comments

giacomorebonato picture giacomorebonato  路  3Comments

etinif picture etinif  路  3Comments

bakedog417 picture bakedog417  路  3Comments