I started writing my @actions with async/await and this seems to fail when running MobX in strict mode:
@action updateDocument = async () => {
this.isSaving = true;
....
}
mobx.js:2077 Uncaught (in promise) Error: [mobx] Invariant failed: It is not allowed to create or change state outside an `action` when MobX is in strict mode. Wrap the current method in `action` if this state change is intended
use async action (()=>...
I'll make sure to add it to the docs
Op vr 3 jun. 2016 06:17 schreef Jori Lallo [email protected]:
I started writing my @actions with async/await and this seems to fail
when running MobX in strict mode:@action updateDocument = async () => {
this.isSaving = true;
....
}mobx.js:2077 Uncaught (in promise) Error: [mobx] Invariant failed: It is not allowed to create or change state outside an
actionwhen MobX is in strict mode. Wrap the current method inactionif this state change is intendedโ
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/mobxjs/mobx/issues/299, or mute the thread
https://github.com/notifications/unsubscribe/ABvGhJrnMLYhOFPC7V5VTuNLlEUcGAzBks5qH6rHgaJpZM4ItMJV
.
@mweststrate ๐
Updated the docs: http://mobxjs.github.io/mobx/refguide/action.html
@mweststrate After trying this out it seems that, at least with Babel6, async is unable to play ball with action:
ERROR in ./src/stores/UserStore.js
Module build failed: SyntaxError: /Users/jorilallo/projects/atlas/src/stores/UserStore.js: Unexpected token (47:65)
45 | }
46 |
> 47 | @action updateDocument = async action(() => {
| ^
48 | this.isLoading = true;
49 |
50 | })
Thanks for noticing! Will investigate, in the mean time () => action(() => { .. })() probably works as workaround (or disable strict mode)
@mweststrate ended up just disabling strict mode but will be interested to hear the outcome of this :)
+1, disabled strictMode as well because of the same reason
Did a quick test, simply putting parentheses around the expression seems to solve this issue (at least parsing). Can you guys verify this? If it doesn't fix it, could you share your .babelrc file? Then I'll take a further look later this week (conference tomorrow). Thanks!
class Store {
@action test = async (action(() => {
}));
}
@mweststrate I don't think it's possible. they way that you wrote it, the babel compiler compiles it into
test = async(action( function () { ... } ))
which babel thinks async has been a defined function somewhere in your code base.
Any other suggestion? I don't really want to go back to then() function again.
Would you mind creating a small github project in which I can quickly test? Then I'll try to dive into it somewhere tomorrow, otherwise it probably will be thursday.
@mweststrate I think it has nothing to do with mobx. This is how babel transpiles the code.
if you have the following ES6
const fn = async () => {}
after babel transformation you get this
"use strict";
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
var fn = function () {
var ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
case "end":
return _context.stop();
}
}
}, _callee, undefined);
}));
return function fn() {
return ref.apply(this, arguments);
};
}();
as if you have this which you are referring to
const fn = async(() => {})
it transforms to
"use strict";
var fn = async(function () {});
so symatically async () => {} is not the same as async(() => {})
Async will not generate useful code indeed for anonymous functions inside the async function. (Which makes lot of sense). To address this 2.3.0 will introduce a new feature, runInAction, which is basically sugar for action(() => { stuff })(), so that the above could be written as follows:
updateDocument = async () => {
await somethingAsync()
await somethingElse()
runInAction("updating document", () => {
this.isLoading = true;
})
}
Thanks Michel!
On Tue, Jun 14, 2016 at 1:06 AM Michel Weststrate [email protected]
wrote:
Closed #299 https://github.com/mobxjs/mobx/issues/299.
โ
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/mobxjs/mobx/issues/299#event-691470811, or mute the
thread
https://github.com/notifications/unsubscribe/AAB66VSfRJrNoqQZj_F2P2LqChmo4280ks5qLmD_gaJpZM4ItMJV
.
Most helpful comment
Async will not generate useful code indeed for anonymous functions inside the async function. (Which makes lot of sense). To address this
2.3.0will introduce a new feature,runInAction, which is basically sugar foraction(() => { stuff })(), so that the above could be written as follows: