Closed myasul closed 4 years ago
you cannot await sagas: redux-saga
is explicitly for handling asynchronous side-effects. It is therefore impossible for this library to know which of your sagas it should await and which not (as for example the root-saga runs infinite). that's why anything after the dispatch(END)
will not run on serverside.
does this clarify the behavior?
Thank for your quick response!
I'm sorry for the newbie questions, I'm just quite confused. When does the dispatch(END) being called? The above code works perfectly on the client-side. What it does is it dispatches the FetchAllPizzaAction then the yield take
awaits for the success action from the FetchAllPizzaAction
to be dispatched.
take
Creates an Effect description that instructs the middleware to wait for a specified action on the Store. The Generator is suspended until an action that matches pattern is dispatched.
But from what I read here, you can only dispatch an action and be handled by a single saga. Multiple sagas are not supported (which is what I'm trying to do with the code above.). Just wanted to clarify if that is the case? And a brief explanation of why?
No problem at all. I'm trying to help as good as I can.
So, this library wraps your application using a so called HOC (higher order component). This allows us to intercept getInitialProps
and then stop redux-saga
on server side only. If we wouldn't, the redux-saga
would run infinite and end in a stack overflow at any point.
That's why it works on client side.
Our code is located in one single file; the index.js
:
// Stop saga on the server
if (isServer) {
store.dispatch(END)
await store.sagaTask.toPromise()
}
And that's also the problem right there. If you're running anything asynchronously it comes "to late", meaning END
was already dispatched and the channel (the underlying technology of redux-saga
) has been closed.
Then finally, if you want to take
multiple actions, you're on the right way ;) From the docs:
The most common use case is an array of strings though, so that
action.type
is matched against all items in the array (e.g.take([INCREMENT, DECREMENT])
and that would match either actions of typeINCREMENT
orDECREMENT
).
Great explanation! It all makes sense to me now. I got it working as well. Thanks a lot again for the time!
No problem at all. Glad I could help!
@myasul Could you explain how you managed to solve this? I'm having the exact same problem.
I am running this code in the server-side of our project. What it does is to fetch all the pizzas in a menu then waiting if the saga for the action I first dispatched succeeded. It will then fetch the default selected pizza after. But it seems that it is returning prematurely and not waiting the
take
action to finish (I also tried race but got the same result.Am I missing something? I tried using takeEvery and takeLatest in the rootSaga calling this saga but same outcome.