Consider the following example with MobX 5.15.4:
class Store {
@observable.shallow items = [];
}
const store = new Store();
store.items = [5, 6, 7, 8, 9];
Array.prototype.push.apply(store.items, [10, 11, 12, 13, 14]);
Array.prototype.unshift.apply(store.items, [0, 1, 2, 3, 4]);
Calling Array.prototype.unshift for observable array doesn't work for me (while Array.prototype.push works). Here is a stack trace:
mobx.module.js:3390 Uncaught Error: [mobx.array] Index out of bounds, 14 is larger than 10
at Array.set (mobx.module.js:3390)
at Object.set (mobx.module.js:3058)
at Proxy.unshift (<anonymous>)
at Module../index.js (index.js:30)
at __webpack_require__ (bootstrap:89)
at Object.0 (index.js:6200)
at __webpack_require__ (bootstrap:89)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at index.js:1
Array.prototype.splice also doesn't work:
Array.prototype.splice.apply(store.items, [0, 0].concat([0, 1, 2, 3, 4]));
Is it a bug or do I misunderstand something? I guess that I should use an observable array's prototype to make it working. I tried the following but still no luck:
const observableArrayPrototype = store.items.__proto__;
observableArrayPrototype.unshift.apply(store.items, [0, 1, 2, 3, 4]);
That is correct, these methods get overridden by mobx to be able to trap
their behavior. I don't think there is any reason in the first place to
call those methods from the prototype, as they can be accessed through the
instance? So recommend to use store.items.unshift etc directly.
On Mon, Jun 8, 2020 at 3:34 PM Dmitriy Pushkov notifications@github.com
wrote:
Consider the following example with MobX 5.15.4:
class Store {
@observable.shallow items = [];}
const store = new Store();store.items = [5, 6, 7, 8, 9];Array.prototype.push.apply(store.items, [10, 11, 12, 13, 14]);Array.prototype.unshift.apply(store.items, [0, 1, 2, 3, 4]);Calling Array.prototype.unshift for observable array doesn't work for me
(while Array.prototype.push works). Here is a stack trace:mobx.module.js:3390 Uncaught Error: [mobx.array] Index out of bounds, 14 is larger than 10
at Array.set (mobx.module.js:3390)
at Object.set (mobx.module.js:3058)
at Proxy.unshift ()
at Module../index.js (index.js:30)
at __webpack_require__ (bootstrap:89)
at Object.0 (index.js:6200)
at __webpack_require__ (bootstrap:89)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at index.js:1Array.prototype.splice also doesn't work:
Array.prototype.splice.apply(store.items, [0, 0].concat([0, 1, 2, 3, 4]));
Is it a bug or do I misunderstand something? I guess that I should use an
observable array's prototype to make it working. I tried the following but
still no luck:const observableArrayPrototype = store.items.__proto__;observableArrayPrototype.unshift.apply(store.items, [0, 1, 2, 3, 4]);
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/mobxjs/mobx/issues/2370, or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN4NBG5LYU22Z46L24QQ7DRVTZHRANCNFSM4NYPACXA
.
I have items that I need to prepend in a separate array so using apply is the only way to do it per single call. Here is an answer to this question on StackOverflow proposing to use Object.getPrototypeOf for accessing object's prototype but unfortunatelly it also doesn't work in my current setup for some reason.
No idea, how to solve it in general, but both push and unshift accept multiple arguments, so it's easily solvable (see my SO answer).
You can use the spread operator if you need to unshift or push arrays. Note that spreading arguments is dangerous on large collections (javascript has a hardcoded limit on the amount of arguments. You can use spliceWithArray from mobx arrays as well to efficiently merge in an collection; for example item.spliceWithArray(0, 0, [0,1,2,3]) to unshift some items.
@Maaartinus @mweststrate Thanks for pointing out spread operator, guys. I totally forgot about it.
My collection is not too big (at least a number of items appended or prepended at once is less than 100). I'll try to go with spliceWithArray though I didn't find it documented here.
Most helpful comment
You can use the spread operator if you need to unshift or push arrays. Note that spreading arguments is dangerous on large collections (javascript has a hardcoded limit on the amount of arguments. You can use
spliceWithArrayfrom mobx arrays as well to efficiently merge in an collection; for exampleitem.spliceWithArray(0, 0, [0,1,2,3])to unshift some items.