Via the code following I get this error:
error: Error: [mobx-state-tree] Cannot modify
'AuthenticationStore@<root>', the object is protected and can only be
modified by using an action.
the code (generator) in question:
.model('AuthenticationStore', {
user: types.frozen(),
loading: types.optional(types.boolean, false),
error: types.frozen()
})
.actions(self => ({
submitLogin: flow(function * (email, password) {
self.error = undefined
self.loading = true
self.user = yield fetch('/api/sign_in', {
method: 'post',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
'user' : {
'email': email,
'password': password
}
})
}).then(res => {
return res.json()
}).then(response => {
self.loading = false // the error happens here!
return response.data
}).catch(error => {
console.error('error:', error)
// self.error = error
})
}), ...
The question: is this not permitted in a generator, is there a better way to update this particular state or does it need to be wrapped by a try/catch?
As always thanks is advance for any and all feedback!
The problem is you're calling then
on the Promise returned by fetch()
, and the function you pass to then
is not an action. Note that functions that run within an action (or flow) do not count as the action itself.
Since you're using yield
, you don't need to call then
or catch
on the Promise returned by fetch()
. Instead, wrap it in a try/catch:
submitLogin: flow(function* (email, password) {
self.error = undefined;
self.loading = true;
try {
const res = yield fetch('/api/sign_in', {
method: 'post',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
'user' : {
'email': email,
'password': password
}
})
});
const response = yield res.json();
self.loading = false;
self.user = response;
} catch(error) {
console.log('error: ', error);
self.error = error;
}
}