Open xmaster484 opened 7 years ago
You should post example code. It's hard to understand what you mean by 'pass the dispatch'?
Are you saying that you have a recursive function within process() that is dispatching multiple actions? An error might be occurring after the first dispatch that essentially stops subsequent actions from being dispatched properly. Might be related to #50.
@ksloan const getDataUntilDone = (data, dispatch) => { const links = data.links.next; dispatch(CONCAT_DATA(data.data)); if (links !== null) { axios.get(links).then(resp => { getDataUntilDone(resp.data, dispatch); }); } };
export const dataLogic = createLogic({ type: SOME_TYPE, process({ getState, action }, dispatch, done) { axios.get('some-api-url') .then(resp => getDataUntilDone(resp.data, dispatch)) .catch((err) => { console.error(err); }) .then(() => done()); }, });
Basically the first dispatch call in getDataUntilDone works, and even if i were to copy the dispatch call a few more times, they would all dispatch fine.
The problem is that it wont dispatch anymore after it starts recursing. before recursion starts its fine, after it starts, it stops working.
CONCAT_DATA is the action that concats the API resultset to the store, I know it works fine with the reducer and everything (manual testing).
Any ideas?
Edit: Ill also like to add that the logic for getting all the pages and existing works fine, I have outputted all the the results i have received and they were all there, literally only the dispatch isnt going through.
My guess is that done() is being called after the first getDataUntilDone() invocation, but before the second. Do some logging to make sure that's not the case, and try returning the promise from getDataUntilDone(). ex... return axios.get(links)...
@ksloan seems like you were right, the done() was being executed before the other dispatches, but adding the return just made it dispatch twice (instead of once when there was no return) and then return, instead of dispatching all 7 actions that it should have been.
Edit: I feel like there should be a better way to ingest paginated API results, are you familiar with any other way? This method seems a bit quick and dirty.
I would solve it with some RxJS, like so:
import { Subject } from "rxjs/Subject";
import "rxjs/add/operator/finally";
export const dataFetchLogic = createLogic({
type: FETCH_PAGINATED,
process({ action, axios }, dispatch, done) {
const startUrl = action.payload.url;
// Lets use a stream to handle data, errors and final completion
const data$ = new Subject();
// This recursively fetches and puts data into data$
const fetchData = (url) => {
axios
.get(url)
.then((res) => {
data$.next(res.data);
const nextUrl = res.links.next;
if (nextUrl) {
// Get next chunk of data
fetchData(nextUrl);
} else {
// No more chunks to get
data$.complete();
}
})
.catch((err) => data$.error(err));
}
data$
// This makes sure logic is done when data$ ends with complete or some error
.finally(done)
.subscribe(
// Next data chunk handler, saves via another action
(data) => {
dispatch(SAVE_AND_CONCAT(data));
},
// Error handler, if any recursive fetching fails
(err) => {
console.log(err);
}
);
fetchData(startUrl);
}
})
Not sure if this is the correct place for this. I am currently using redux logic and i'm trying to deal with a paginated API. I am trying to pass dispatch to an auxiliary function that will attempt to pull all the pages of the resultset and concat them to the store. I pass the dispatch to this auxiliary function and it works fine, but when i recurse on this same auxiliary function, to try to pull the next set of results and pass the dispatch in again, it doesn't actually dispatch any actions, and it doesn't throw any errors. I have made sure multiple dispatches were turned on by dispatching the same action 3 times before the recursion started and that worked.
Any ideas why the dispatch wont work past the first auxiliary function call?