Front-End Insights

How to update MobX store using AJAX

MobXProgrammingReact

It seems like it is a “MobX month” on the Front-End Insights blog… It is the third blog post about this great library in October! In today’s post I will show you how to update MobX store using AJAX. But first I will compare it to Redux to show you how much easier it is to do it with MobX. Don’t worry! It is really simple! Like all things in MobX!

How it is done in Redux

As usual, I will compare MobX to Redux which I know best and have used for the last year very intensively. In Redux, updating the store using the AJAX call is not too difficult but may be confusing at the beginning. Let’s quickly check how we usually do it in Redux.

Fetch and action creators

Basically, we should have a bunch of action creators which are dispatched before the fetch, after success or in case of an error. They might look like this:

import fetch from 'isomorphic-fetch'

export const FETCH_STARTED = 'FETCH_STARTED'
export function fetchStarted() {
  return {
    type: FETCH_STARTED,
  }
}

export const FETCH_COMPLETED = 'FETCH_COMPLETED'
export function fetchCompleted() {
  return {
    type: FETCH_COMPLETED
  }
}

export const FETCH_ERROR = 'FETCH_ERROR'
export function fetchError() {
  return {
    type: FETCH_ERROR
  }
}

export function fetchAll() {
  return function (dispatch) {
    dispatch(fetchStarted());

    return fetch('https://api.github.com/repos/burczu/react-redux-ajax-example/branches')
      .then(() => dispatch(fetchCompleted()))
      .catch(() => dispatch(fetchError()));
  }
}

As you may have noticed, we have three action creators for all three mentioned situations. We also have a plain function, fetchAll, which dispatches the fetchStarted function at the start. Then it makes a fetch and dispatches the fetchCompleted action creator in case of success or fetchError in case of any exception.

Reducer and middleware

To keep everything clear, let’s take a quick look at the reducer:

const reducer = (state = { fetched: false }, action) => {
  switch (action.type) {
    case 'FETCH_STARTED':
      return { ...state, fetched: false };
    case 'FETCH_COMPLETED':
      return { ...state, fetched: true };
    default:
      return state;
    }
};

As you can see, it is quite a typical reducer. Nothing to explain.

But that is not all. Please take a look again at the example from the previous section. The fetchAll function returns another function which gets dispatch as the parameter. So how should we provide it to this function? Some of you may remember my article about [Redux Thunk]](http://frontendinsights.com/redux-thunk-populate-various-reducers/). That’s right! We additionally have to use the Redux Thunk middleware to make it work:

import { createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';

...

const store = createStore(reducer, applyMiddleware(thunkMiddleware));

When that’s done, we can do this:

store.dispatch(actions.fetchAll());

As I said – this is not so difficult but requires quite a lot of boilerplate code. But this article is about how to update MobX store using AJAX. So let’s leave Redux and move our focus to the MobX library!

P.S. The working example from this section is available on GitHub – here’s the link to the repo.

Let’s update MobX store using AJAX

You probably might have noticed that dealing with MobX is extremely simple. The same is when we want to update MobX store using AJAX!

MobX store

Just take a look at the example of the MobX store:

import { observable } from 'mobx';
import fetch from 'isomorphic-fetch';

class Store {
  @observable fetched = false;

  fetch() {
    fetch('https://api.github.com/repos/burczu/react-redux-ajax-example/branches')
      .then(() => this.fetched = true)
      .catch(() => this.fetched = false);
  }
}

export default Store;

As you may already know, in MobX we don’t have any additional layers between the store and the React components. So usually the store contains all methods which affect the state. And these methods are directly available to the components. That’s why we just have the fetch method inside the store. This method simply makes a fetch and in case of success or error, it just changes the state.

Using the store in the React component

Let’s additionally take a look at the component:

import React from 'react';
import { observer } from 'mobx-react';

@observer
class AppComponent extends React.Component {
  componentDidMount() {
    this.props.store.fetchData();
  }

  render() {
    return (
      <div className="index">
        <span>{`${this.props.store.fetched}`}</span>
      </div>
    );
  }
}

export default AppComponent;

In the component we just call the fetchData method and, when the state changes, it will be reflected in the view immediately! I told you it will be simple 😉

P.S. The working example from this section is available on GitHub – here’s the link to the repo.

Summary

The more I know about MobX, the more I like it. And I have started to think that it might be an even better approach to state management than Flux… Now that I know how easy it is to update MobX store using AJAX, I think I’m even more convinced. The one thing I know for sure: I will keep on digging in MobX so you can expect more posts about it! 😉

Related Post

I recommend Nozbe

Simply Get Everything Done

Get your tasks and projects done thanks to Nozbe system and apps for the Mac, Windows, Linux, Android, iPad and iPhone.

If you want to know more about Nozbe and its capabilities, please take a look at my article about this great application.


  • You forgot to show how you get your store into “this.props.store.fetchData();”

    IMHO it would be better to just import your store directly in your simple use case. There’s no convincing argument for using dependency injection in javascript. Everything es easily mockable/monkeypatched in JS.

  • Vladimir Migalkin

    You should take a look on https://github.com/mobxjs/mobx-utils and method fromPromise.
    “fromPromise takes a Promise and returns an object with 3 observable properties that track the status of the promise.”

    • awesome! didn’t know it (still learning MobX)… thanks!

      • Vladimir Migalkin

        You welcome!