Categories
Mobx

Creating and Using Mobx Observable Maps

Spread the love

Mobx is a state management solution for JavaScript apps. It lets us observe values from a store and then set the values, which will be immediately reflected in the store.

In this article, we’ll look at how to create and use Observable Maps with Mobx.

Observable Maps

Observable maps are a collection of key-value pairs that we can get and set. The value changes can be watched.

To create an Observable map, we can use the observable.map method as follows:

import { observable, autorun } from "mobx";

const values = {
  foo: 1,
  bar: 2
};

const observableMap = observable.map(values);

autorun(() => console.log(observableMap.toJS()));

In the code above, we defined an Observable map by creating an values object and then passing in values into the observable.map method.

It also optionally takes a second argument to specify various options.

We can also pass in an ES6 JavaScript Map instance as follows:

import { observable, autorun } from "mobx";

const values = new Map([["foo, 1"], ["bar", 2]]);
const observableMap = observable.map(values);
autorun(() => console.log(observableMap.toJS()));

In both examples, the autorun function watches the value of the Observable map as it changes.

It’ll log the value when it’s created in both examples.

A Mobx Observable map has the same methods as an ES6 Map and more. They’re the following:

  • has(key) — returns whether a map has an entey with the provided key.
  • set(key, value) — sets the given key to value . The provided key will be added to the map if it doesn’t exist yet
  • delete(key) — deletes the given key and its value from the map
  • get(key) — returns the value at the given key or undefined if the key isn’t found
  • keys() — returns an iterator to iterate through all the keys in a map in the order that they’re inserted
  • values() — returns an iterator to iterate through all values present in the map in the order that they’re inserted.
  • entries() — returns an iterator to iterate through all key-value pairs in the map with each entry being an array with the key and value.
  • forEach(callback) — runs the callback for each key/value pair in the map
  • clear() — removes all entries from a map
  • size — returns the number of entries in a map
  • toJS() — converts an Observable map to a normal map
  • toJSON() — returns a shallow plain object representation of the map. We can use mobx.toJS(map) to deep copy a map
  • intercept(interceptor) — registers an interceptor that’ll be triggered before any changes are applied to the map
  • observe(listener, fireImmediately?) — attaches a listener that listens to changes in the map
  • merge(values) — copy all entries from the provided object into the map
  • replace(values) — replaces the entire contents of the map with the provided values.

Options

The second argument takes some options to modify the Observable map’s behavior.

We can pass in { deep: false } to create a shallow map to prevent a nested Observable map from being created.

For example, if we write:

import { observable, autorun } from "mobx";
const values = {
  foo: 1,
  bar: {
    baz: 2
  }
};
const observableMap = observable.map(values);
autorun(() => console.log(observableMap.toJS()));

We get a nested Observable map since we have a nested object. The value of bar is an Observable map.

On the other hand, if we write:

import { observable, autorun } from "mobx";
const values = {
  foo: 1,
  bar: {
    baz: 2
  }
};
const observableMap = observable.map(values, { deep: false });
autorun(() => console.log(observableMap.toJS()));

Then we get the plain object:

{
  baz: 2
}

as the value of bar .

Another option is the { name: "my map" } option, which names the Observable map so we can identify it when we’re debugging with MobX dev tools.

Conclusion

We can create maps that are observable with MobX. It’s like a regular JavaScript map except that it has additional methods.

Also, we can watch is value and manipulate it like a regular map.

By default, Observable maps are recursive, so the values of an Observable map entry may also be an Observable map. We can set the deep option to false to disable this behavior and then the nested values will become a plain object.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *