15

I am trying to understand how to use observable array with Mobx.

I have a hard time to figure out why this:

let entities = observable([]);
entities[0] = "foo";
autorun(() =>{
  console.log(entities);
});

writes:

[$mobx: Object]
0: (...)
1: (...)
2: (...)
3: (...)
4: (...)
5: (...)
6: (...)
7: (...)
8: (...)
9: (...)
10: (...)
11: (...)
12: (...)
13: (...)
14: (...)
15: (...)
16: (...)
17: (...)
...
999: (...)

Instead of a classic array?

dagatsoin
  • 2,626
  • 6
  • 25
  • 54

2 Answers2

38

Figure out!

As stated in the docs

Bear in mind that Array.isArray(observable([])) will yield false, so whenever you need to pass an observable array to an external library, it is a good idea to create a shallow copy before passing it to other libraries or built-in functions (which is good practice anyway) by using array.slice() or array.peek(). So Array.isArray(observable([]).slice()) will yield true.

The doc exemple show us a todos.filter() which could lead to confusion because todos looks like a real JS Array. But it is not.

So for my exemple to work I just have to console.log(entities.slice()) which will display a real JS array.

dagatsoin
  • 2,626
  • 6
  • 25
  • 54
  • 1
    I had this problem using ` – thund May 04 '16 at 21:01
  • 1
    kind of an ugly hack, wish there was a better solution for this, somehow to define observable arrays as pure arrays – Jony-Y Oct 08 '17 at 11:56
  • 1
    Same Problem...i get the following error : Cannot read property 'slice' of undefined – Newton Sheikh Jan 29 '18 at 06:59
  • also fixed for me *"mobx read out of bounds [0]"* warning when passing the observable array _gifted chat_ module. – Karl Adler Sep 07 '21 at 06:14
2

Another way to log mobx observable is with toJS method

import { toJS } from 'mobx';

class Store {
  @observable
  fruits = ['Apple', 'Banana'];

  constructor() {
    console.log('this.views :', toJS(this.data));
  }
}

export default new Store();

Hope this help. Source

Wachid
  • 447
  • 5
  • 8