Mobx: @transaction decorator

Created on 15 Apr 2016  路  7Comments  路  Source: mobxjs/mobx

Would be super cool to be able to use transaction as a decorator.

Before

class StuffDoer {
  doStuff() {
    return transaction(() => {
      // Do stuff...
    })
  }
}

After

class StuffDoer {
  @transaction
  doStuff() {
    // Do stuff.
  }
}
馃崡 enhancement

Most helpful comment

Thanks for the suggestion. I really like the idea, then I figured it could be generalized a bit, as transactions also form nicely conceptual groups of actions.

So here is some work in progress:

  • @action decorator for instance methods
  • action(function), returns "the same" function, wrapped in a transaction.
  • action(logName, function), the same, but with an improved logname.

Example usage of case 1 and 3:

    @action
    createRandomContact() {
        this.pendingRequestCount++;
        superagent
            .get('https://randomuser.me/api/')
            .set('Accept', 'application/json')
            .end(action("createRandomContact-callback", (error, results) => {
                if (error)
                    console.error(error);
                else {
                    const data = JSON.parse(results.text).results[0];
                    const contact = new Contact(this, data.dob, data.name, data.login.username, data.picture)
                    contact.addTag('random-user');
                    this.contacts.push(contact);
                    this.pendingRequestCount--;
                }
            }));
    }

Which then results in the following
action-decorator

@amsb, thanks for the inspiration in mobx-reactor. It might be confusing that this decorator would also be called @action, maybe @transaction (collides with mobx.transaction) or @withTransaction would be better.

What do you guys think?

All 7 comments

Thanks for the suggestion. I really like the idea, then I figured it could be generalized a bit, as transactions also form nicely conceptual groups of actions.

So here is some work in progress:

  • @action decorator for instance methods
  • action(function), returns "the same" function, wrapped in a transaction.
  • action(logName, function), the same, but with an improved logname.

Example usage of case 1 and 3:

    @action
    createRandomContact() {
        this.pendingRequestCount++;
        superagent
            .get('https://randomuser.me/api/')
            .set('Accept', 'application/json')
            .end(action("createRandomContact-callback", (error, results) => {
                if (error)
                    console.error(error);
                else {
                    const data = JSON.parse(results.text).results[0];
                    const contact = new Contact(this, data.dob, data.name, data.login.username, data.picture)
                    contact.addTag('random-user');
                    this.contacts.push(contact);
                    this.pendingRequestCount--;
                }
            }));
    }

Which then results in the following
action-decorator

@amsb, thanks for the inspiration in mobx-reactor. It might be confusing that this decorator would also be called @action, maybe @transaction (collides with mobx.transaction) or @withTransaction would be better.

What do you guys think?

@mweststrate

So would it wrap functions?

const doSomething = action(function() {
  // code
}, 'Does something')

and then whenever you have something like

autorun(() => doSomething())

It would log the action?

@AriaFallah exactly, and all changes made in doSomething are processed in a transaction and logged underneath the action.

Sounds like a very good idea. It's like a more automatic redux.

I really like this! I've been meaning to dig in a bit more to see how state changes could naturally be traced with MobX's internal machinery so I'm looking forward to see how you implemented it. Beyond logging to console during local development, I will be curious to see how it might be built upon to provide an extension point for gathering analytics and exception analysis.

As far as naming, withTransaction seems to capture the essence without being confused with concepts from flux architecture.

MobX 2.2 introduced @action. No need for @transaction anymore :) Thanks @jeffijoe @amsb for igniting this idea!

Was this page helpful?
0 / 5 - 0 ratings