7

I got this waring message from Mobx.

[mobx.array] Attempt to read an array index (0) that is out of bounds (0). Please check length first. Out of bound indices will not be tracked by MobX

@observable checks = {
      deviceType: ['phone','laptop', ...],
      deviceTypeChecks: [],
      ...
    }

@action
selectAllChecks = (target, type) => {
     const targetChecks = []
     if (this.checks[target].length !== this.checks[type].length) {
        this.checks[target].forEach(el => targetChecks.push(el))
      }
     this.checks[type] = targetChecks
}

How can I remove that warning? However, this code has no problem. It works well.

I'm using selectAllChecks function by onChange function.

const {
  deviceType,
  deviceTypeChecks
} = this.props.store.checks

<label className="mr10">
          <input
            type="checkbox"
            checked={deviceType.length === deviceTypeChecks.length}
            onChange={() =>
              selectAllChecks('deviceType', 'deviceTypeChecks')
            }
          />
          <span>All device type</span>
        </label>

I have to 4 version for IE.

"mobx": "^4.1.0",
"mobx-react": "^5.2.6",

Is there any other solution?

kkangil
  • 966
  • 1
  • 4
  • 22
  • 1
    Should you be checking if `this.checks[target].length > 0` before comparing lengths? It looks like you are reading an index before the observable has acknowledged new data, as the comparison of lengths shown above could always return true if the compared array has not collected any items. I am more familiar with MST and have not used direct mobx-react much. – Nicholas Pesa Mar 27 '19 at 03:22
  • I tried to check `this.checks[target].length` as you said. But the warning is still occuring. thanks – kkangil Mar 27 '19 at 03:31
  • Can you show how/where the function is being used? – Nicholas Pesa Mar 27 '19 at 03:32
  • please check edited code above. I'm using the function by onChange event. – kkangil Mar 27 '19 at 04:13
  • It is not related to `checks` obj, cause it is not an array. Check where do you have an observable array in the code. – felixmosh Mar 27 '19 at 07:00
  • @felixmosh `console.log(deviceType)` returns observable array. – kkangil Mar 27 '19 at 09:03

5 Answers5

4

Mobx can make observable of dynamic objects (that it does not know in advance)

but if you look on the object at client side debugger (console.log(myObject)) you can see it's not a regular JS object but some Proxy object of Mobx. This is unlike observable of primitive values like numbers and strings.

To avoid this kind of warning, you can use toJS method which converts an (observable) object to a javascript structure.

For example, this code return warning

  autorun(
        () => {
          if (this.props.store.myObject !== null ) 
          {
            this.updateSomeUi(this.props.store.myObject);
          }
        }
    );

you can fix this with:

  import { toJS } from 'mobx';  
...
  autorun(
        () => {
          if (this.props.store.myObject !== null ) 
          {
            let myStruct = toJS(this.props.store.myObject);
            this.updateSomeUi(myStruct);;
          }
        }
    );
Citizen-Dror
  • 427
  • 2
  • 12
4

Another conflict with Flatlist when your data array length is 3 or 5 or 7 and etc... but used numColumns={2}. Changed to numColumns={1} warning error solved. But solution for this issue use Javascript slice method

<FlatList
   data={ProductStore.dataFood.slice()} // added .slice()
   extraData={ProductStore.dataFood}
   refreshing={ProductStore.productsLoading}
   numColumns={2} // number 2 conflict when your array length is 3 or 5 or 7 and etc...
   renderItem={this._renderItemFood}
   keyExtractor={(item, index) =>
     index.toString()
   }
/>
Nijat Aliyev
  • 292
  • 1
  • 9
0

What happens if you change your @action to this:

@action
selectAllChecks = (target, type) => {
      this.checks[type] = this.checks[target].map((value) => value);
}

Does that still show the mobx out of bounds error?

Nicholas Pesa
  • 1,906
  • 2
  • 22
  • 37
0

It appears that you are trying to access an element of an observable array, and that element does not exist. You have two observable arrays, and one of those, deviceTypeChecks has no elements. However, the code as it is seems okay. Is somewhere else in your code accessing this this array?

cham
  • 4,095
  • 4
  • 32
  • 48
0

I got the same problem today, after checking everthing, I've found the problem is that I defined the wrong type of the data, so mobx cannot read it normal.

the wrong defined array:

exampleArr: types.array(types.model({
    dataOne: type.string,
    dataTwo: type.number   <-- this should be a string but I defined it as number
}))

after I changed it to the right type, it works well

exampleArr: types.array(types.model({
    dataOne: type.string,
    dataTwo: type.string   
}))