Mobx-state-tree: [TypeScript] Async action functions using `runInAction`

Created on 10 Jul 2018  路  1Comment  路  Source: mobxjs/mobx-state-tree

I have:

  • [x] A conceptual question.

    • [x] I've checked documentation and searched for existing issues

    • [x] I tried the spectrum channel first

The documentation recommends using flow for asynchronous actions, however in TypeScript that's not a great solution because generators are not type safe. So I'd like to use asynchronous functions. Declaring separate functions for each stage of an asynchronous flow as described here works, but is there any way to do it inline? I would've thought runInAction from MobX would do the trick:

const Foo = types
  .model({
    x: types.number
  })
  .actions(self => ({
    async waitThenSet(x: number) {
      await sleep(1000);
      runInAction(() => {
        self.x = x;
      });
    }
  }));

but it blows up at runtime with

[mobx-state-tree] Cannot modify 'AnonymousModel@', the object is protected and can only be modified by using an action.

I assume this is because the model is protected from editing, even within actions, unless they are actions associated with the model somehow. Is there a way to give inline actions this privilege?

Most helpful comment

You could introduce your own local runInAction:

.actions(self => ({
   runInAction(fn) {
      return fn()
   }
}))
.actions(self => ({
    async waitThenSet(x: number) {
      await sleep(1000);
      self.runInAction(() => {
        self.x = x;
      });
    }
  }));

You could extract this to a utility type if you want and compose from that.

The mobx run-in-action does not suffice indeed, because it doesn't know where in the tree it is being invoked, how to run middleware etc etc

>All comments

You could introduce your own local runInAction:

.actions(self => ({
   runInAction(fn) {
      return fn()
   }
}))
.actions(self => ({
    async waitThenSet(x: number) {
      await sleep(1000);
      self.runInAction(() => {
        self.x = x;
      });
    }
  }));

You could extract this to a utility type if you want and compose from that.

The mobx run-in-action does not suffice indeed, because it doesn't know where in the tree it is being invoked, how to run middleware etc etc

Was this page helpful?
0 / 5 - 0 ratings