I have 3 different ajax functions and when I call them via Mobx store in my React Component those ajax are firing one by one Synchronously but I want them to fire asynchronously. When I put those Ajax functions back to my React Component and after that, if I call those functions those are firing asynchronously.
import { observable, action } from 'mobx';
export class SessionEntryStoreClass {
@observable fetched = false;
@observable sessionPlInfo = {};
@observable sessionWinLossList = [];
@observable sessionEntriesList = [];
fetch(sessionId) {
this.fetchList(sessionId)
this.fetchPlInfo(sessionId)
this.fetchWinLossList(sessionId)
}
@action
fetchList(sessionId) {
axios.get('/session_entries', {
params : {
session_id: sessionId
}
})
.then((res) => {
this.sessionEntriesList = res.data
})
.catch(() => this.fetched = false);
}
@action
fetchPlInfo(sessionId) {
axios.get('/session_entries/session_plinfo', {
params : {
session_id: sessionId
}
})
.then((res) => this.sessionPlInfo = res.data)
.catch(() => this.fetched = false);
}
fetchWinLossList(sessionId) {
axios.get('/session_entries/winlosslist/' + sessionId, {
params : {
session_id: sessionId
}
})
.then((res) => {
this.sessionWinLossList = res.data
})
.catch(() => this.fetched = false);
}
}
I'm not sure whether I understand the question, request api's are asynchronous by nature and there is nothing mobx can do to either enforce or undo this. What makes you conclude the requests are synchronous now?
I am using AXIOS ajax library so what actually is I have 3 ajax functions and I want them to fire Asynchronously so I have these observable variables and I am setting their value on success response. If I remove these variables in success response my ajax start working asynchronously so maybe mobx causing my request to be synchronous
@observable sessionPlInfo = {};
@observable sessionWinLossList = [];
@observable sessionEntriesList = [];
I would investigate your use of axios. A cannot really imagine how this would be affected by mobx. Also note that requests can appear to be synchronous without being really so. For example, there is a maximum number of parallel requests that can be send to a host (enforced by the browser), after which the browser starts queuing them.
You can see my above Mobx Store code I am just only sending 3 ajax request. Somehow mobx state is blocking my ajax.
In that case best provide a small(!) reproduction project. Please make sure it includes log statements to demonstrate the requests are actually blocking
I just figured it out why it slow but I do not know how to make it work with 3 different observable variables.
Basically I have 3 observable variable so I am setting those 3 observable variable values one by one via 3 different request which is causing Mobx slow and results are rendering slow but if I convert an observable variable to Object like this then it works fine.
@observable state = {
sessionEntriesList: [],
sessionPlInfo: {},
sessionWinLossList: [],
}
If you want to batch these 3 modifications (so that the component is re-renderer only when all free values are resolved), you have to update them inside a single action. For example:
import { observable, action } from 'mobx';
export class SessionEntryStoreClass {
@observable fetched = false;
@observable sessionPlInfo = {};
@observable sessionWinLossList = [];
@observable sessionEntriesList = [];
fetch(sessionId) {
Promise.all([
this.fetchList(sessionId),
this.fetchPlInfo(sessionId),
this.fetchWinLossList(sessionId),
])
.then(action(data => { // action !!!
this.sessionEntriesList = data[0];
this.sessionPlInfo = data[1];
this.sessionWinLossList = data[2];
}))
.catch(() => this.fetched = false);
}
fetchList(sessionId) {
return axios.get('/session_entries', {
params: {
session_id: sessionId
}
})
.then(res => res.data)
}
fetchPlInfo(sessionId) {
return axios.get('/session_entries/session_plinfo', {
params: {
session_id: sessionId
}
})
.then(res => res.data)
}
fetchWinLossList(sessionId) {
return axios.get('/session_entries/winlosslist/' + sessionId, {
params: {
session_id: sessionId
}
})
.then(res => res.data)
}
}
Note that if these 3 values must be always updated together it could make sense to wrap them into an immutable object stored in single observable field.
@urugator
Thanks, your solution worked perfectly. The use of action solved my issue.
Most helpful comment
If you want to batch these 3 modifications (so that the component is re-renderer only when all free values are resolved), you have to update them inside a single action. For example:
Note that if these 3 values must be always updated together it could make sense to wrap them into an immutable object stored in single observable field.