Reputation: 183
I am dispatching an action, which is a put call to my api (createNote).
After finishes saving, I need to then run another action, which is a fetch call to my api.
Is it possible to correctly wait for the first action to finish before calling the other actions with a similar setup I have now using async actions through saga, without using setTimeout, etc?
form.js
function handleSubmit(id) {
dispatch(createNote(obj));
// need to wait for the above action to finish
dispatch(notesFetch(id));
}
actions.js
export function createNote(obj) {
return {
type: CREATE_NOTE,
payload: {
obj: obj
}
};
}
export function notesFetch(id) {
return {
type: NOTES_FETCH,
payload: id
};
}
saga/index.js
const sagas = [
createNote(),
notesFetch(),
// a bunch of other unrelated sagas in here as well
];
export default function* () {
yield all(sagas);
}
saga/createNote.js
export function* createNote(action) {
if (action['@@redux-saga/SAGA_ACTION']) return;
const params = action.payload;
try {
yield *httpSaga(CREATE_NOTE, call(notesAPI.createNote, params));
} catch (e) {
yield put(error(CREATE_NOTE, e));
} finally {
yield put(doneIndicator(CREATE_NOTE));
}
}
export function* watchCreateNote() {
yield takeEvery(CREATE_NOTE, createNote);
}
export default function* root() {
yield all([
fork(watchCreateNote)
]);
}
saga/notesFetch.js
export function* notesFetch(action) {
if (action['@@redux-saga/SAGA_ACTION']) return;
try {
yield *httpSaga(NOTES_FETCH, call(() =>
notesAPI.getNotes(action.payload)));
} catch (e) {
yield put(error(NOTES_FETCH, e));
} finally {
yield put(doneIndicator(NOTES_FETCH));
}
}
export function* watchNotesFetch() {
yield takeEvery(NOTES_FETCH, notesFetch);
}
export default function* root() {
yield all([
fork(watchNotesFetch)
]);
}
Then, I have the createNotes and notesFetch api calls in a separate api directory, as well as reducers that save to the store. But, my understanding is can put the appropriate async logic in the saga files? What would be the best way to go about this? Thank you!
Upvotes: 0
Views: 288
Reputation: 12174
Well you could dispatch NOTES_FETCH
action in your finally
block inside createNote
watcher.
Given that the API don't have any means to subscribe for updates.
// Saga
function* createNote(action) {
try {
// do something
} finally {
yield put(doneIndicator(CREATE_NOTE));
yield put(notesFetch()); // also dispatch NOTES_FETCH here
}
}
function* notesFetch(action) {
// do something
}
export default function* root() {
yield all([
takeEvery(CREATE_NOTE, watchCreateNote),
takeEvery(NOTES_FETCH, notesFetch),
]);
}
// Component
function handleSubmit(id) {
dispatch(createNote(obj)); // only dispatch CREATE_NOTE action
}
Upvotes: 1