I get this error when i have a very large array and when i used replace function to update it
Uncaught Error: [mobx] Modification exception: the internal structure of an observable array was changed. Did you use peek() to change it?
at e.updateArrayLength (bundle.js:11)
at e.spliceWithArray (bundle.js:11)
at t.replace (bundle.js:11)
at e.value (bundle.js:40)
at F (bundle.js:11)
at e.n (bundle.js:11)
at bundle.js:40
Any help is appreciated
Could you make some reproduction code?(or paste your real code?
@leader22
There are some computations made and just a replace of that array is made , no actual code can be pasted
no actual code can be pasted
How about small repro..?
It makes us easier to help you.
Probably, It is not a mobx issue. Your code that manipulating array has some mistakes, I think...
For example, code like below occurs same error.
const arr = mobx.observable.array([]);
arr.push(1);
arr.push(2);
// peek() returns arr's internal real array
const copy = arr.peek();
// so if you modify it,
copy.push(3);
// all manipulation for arr occurs error
arr.push(3);
// same error
arr.replace([0]);
@leader22
what i found is
I have an array of size 16 then its updated to array size to 1280 that was fine then i updated this array to 124000 , then the lastknownlength variable was updated to 124000 instead of 1280
which gives me this error .
i dont known where we are calculating lastKnownLength
@leader22 Please refer this stackoverflow where the issue is
http://stackoverflow.com/questions/22123769/rangeerror-maximum-call-stack-size-exceeded-why
and
below error shows
Uncaught RangeError: Maximum call stack size exceeded
at Array.splice (
at ObservableArrayAdministration.spliceWithArray (bundle.js:25198)
at ObservableArray.replace (bundle.js:25280)
at bundle.js:78087
line where the error is
var res = (_a = this.values).splice.apply(_a, [index, deleteCount].concat(newItems));
@kamarajuPrathi
OK, I found there're 2 points in this issue.
Uncaught Error: [mobx] Modification exception: the internal structure of an observable array was changed. Did you use peek() to change it?.
This occurs when you manipulate observable array outside mobx.
So, some lines of your code may have problem.
replace() with large arrayCurrently mobx can't handle replace() with large array.
Array.prototype.splice() when replace() array.65536(and reported as bug in webkit)So, replace() with large array ends up with error in some environment.
Work around is not to use replace().
const mobx = require('mobx');
const largeArr = new Array(99999).fill(0);
const arr = mobx.observable([1,2,3]);
// error
// arr.replace(largeArr);
// no error
arr.clear();
for (let i = 0; i < largeArr.length; i++) {
arr.push(largeArr[i]);
}
console.log(arr.length);
@mweststrate
As you commented in this line, it throws in some cases.
Do you have any plan or idea to fix this?
for loop can fix it but it's not good for performance, I think..(just warning is better..?)
The loop should perform better if you use an action so it runs
transactionaly.
On Sun, Mar 5, 2017, 12:14 AM Yuji Sugiura notifications@github.com wrote:
@kamarajuPrathi https://github.com/kamarajuPrathi
OK, I found there're 2 points in this issue.
[1] the original error you reportedUncaught Error: [mobx] Modification exception: the internal structure of
an observable array was changed. Did you use peek() to change it?.This occurs when you manipulate observable array outside mobx.
So, some lines of your code may have problem.
[2] using replace() with large arrayCurrently mobx can't handle replace() with large array.
- mobx uses Array.prototype.splice() when replace() array.
- Some of JavaScript engine has a limit for number of arguments.
- eg) it is 65536(and reported as bug in webkit
https://bugs.webkit.org/show_bug.cgi?id=80797)
So, replace() with large array ends up with error in some environment.
- Chrome: error
- Node: error
- Safari: error
- = webkit
- Firefox: works
- ≠webkit
Work around is not to use replace().
const mobx = require('mobx');
const largeArr = new Array(99999).fill(0);const arr = mobx.observable([1,2,3]);
// error// arr.replace(largeArr);
// no errorarr.clear();for (let i = 0; i < largeArr.length; i++) {
arr.push(largeArr[i]);
}
console.log(arr.length);@mweststrate https://github.com/mweststrate
As you commented in this line
https://github.com/mobxjs/mobx/blob/master/src/types/observablearray.ts#L174,
it throws in some cases.
Do you have any plan or idea to fix this?for loop can fix it but it's not good for performance, I think..(just
warning is better..?)—
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/859#issuecomment-284206084, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAIrclksalSUHeYJuXtO3VdG7ayD-eZnks5rikMpgaJpZM4MQMPl
.
@leader22 thanks for the analysis!
@kamarajuPrathi could you test version 3.1.3, it should fix the large array problem.
@mweststrate I am trying to test using the changes you made in 3.1.3 , the browser gets hanged it never replaces the array elements .I tried to remove observable and tried it works . But i want it to be observables as its something which i am rendering in the UI . any other way to handle this the total number of elements i have is 102400
@kamarajuPrathi hard to comment on that without actual code / reproduction. Converting 100000 items to observables might be expensive. Do the objects themselves need to be observable as well? Did you consider using a shallowArray?
Ok thank you .
I had the same problem cause I made a stupid mistake that I passed the wrong argument when calling Array.prototype.splice(). Here is my usecase:
//store.js
class Application{
@observable list = [];
@action.bound
handleRemove(index){
this.list.splice(index, 1)
}
}
export const application = new Application();
//index.jsx
import {application} from "./store.js"
......
md5-bf61a22aae904f5a5b39c6051d044db8
Hope this will help.
I'm getting the same error after updating mobx version from 4 to 5.
My array is small, and the error appears after using lodash pull on the array.
Please don't comment on old and closed issues :/
This issue is over a year old and closed, please open a new one.
On Tue, Aug 6, 2019 at 1:57 PM Claudio Savino notifications@github.com
wrote:
I'm getting the same error after updating mobx version from 4 to 5.
My array is small, and the error appears after using lodash pull on the
array.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/mobxjs/mobx/issues/859?email_source=notifications&email_token=AAN4NBAGMAYUZAFWJU5HB73QDFRJ5A5CNFSM4DCAYPS2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3U4UUA#issuecomment-518638160,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAN4NBHSQYYZA7H57KW6Y5TQDFRJ5ANCNFSM4DCAYPSQ
.
Most helpful comment
I had the same problem cause I made a stupid mistake that I passed the wrong argument when calling Array.prototype.splice(). Here is my usecase:
Hope this will help.