I'm working on an app which has to manage a large amount of data. In the init process several api calls must be done while the user sees a loading bar.
Here is my init action:
export function init(key) {
return (dispatch, getState) => {
// start init
dispatch(initStart());
setTimeout(() => {
dispatch(initProcess(10));
}, 0)
return Promise.all([
// load users
dispatch(loadUsers(key)).then(() => {
dispatch(initProcess(30));
}),
// load other stuff
// ...
// load articles
dispatch(loadArticles(key)).then(() => {
dispatch(initProcess(60));
}),
// should be executed after all actions/reducers are done
]).then(() => {
setTimeout(() => {
dispatch(initFinish());
}, 700);
});
}
}
So far it works perfectly, but there will be 20k to 50k articles. The backend has to perform some joins to get the data together, so I'm sure I'll get a server timeout if I try to get them in one piece.
The idea is to fetch the total number first and then get the articles in 1k pieces in a loop. But it wont work the way I need it. I'm getting initFinish
dispatched after the articles are counted but not after they are fetched.
Here is the loadArticles
action:
export function loadArticles(key) {
return (dispatch, getState) => {
// check local db first
// get total number
return dispatch(countArticles(key))
.then(result => {
Promise.all([
// No idea how to put the loop in here :(
dispatch(fetchArticles(key, 1000)),
])
});
}
}
I have no loop yet but thats not the point. The logic remains the same. I return the dispatch(countArticles(key))
before fetchArticles
is done.
Has anyone a hint? That would be awesome.
EDIT
coutArticles
and fetchArticles
function countArticles(key) {
return {
[CALL_API]: {
types: [ COUNT_ARTICLES_REQUEST, COUNT_ARTICLES_SUCCESS, COUNT_ARTICLES_FAILURE ],
endpoint: `articles`,
schema: Schemas.ARTICLE_COUNTER
}
}
}
function fetchArticles(key, take, skip) {
return {
[CALL_API]: {
types: [ FETCH_ARTICLES_REQUEST, FETCH_ARTICLES_SUCCESS, FETCH_ARTICLES_FAILURE ],
endpoint: `articles/${take}/${skip}`,
schema: Schemas.ARTICLE_ARRAY
}
}
}
The middleware is the same es here
2. EDIT
if i change
// get total number
return dispatch(countArticles(key))
.then(result => {
Promise.all([
// No idea how to put the loop in here :(
dispatch(fetchArticles(key, 1000)),
])
});
to
// get total number
dispatch(countArticles(key))
.then(result => {
return Promise.all([
// No idea how to put the loop in here :(
dispatch(fetchArticles(key, 1000)),
])
});
I get Uncaught TypeError: Cannot read property 'then' of undefined
on dispatch(loadArticles(key))
.
3. EDIT
Some days later I'm still fighting ^^
Here is the simplified init function, which should (only) get the count result and then fetch the articles:
But for now im failing already here:
export function init(key) {
return (dispatch, getState) => {
countArticles(key).then(result => {
console.log(result);
});
}
}
Output:
Uncaught TypeError: countArticles(...).then is not a function