Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Waiting for an action with takeMaybe / take after END is dispatched for SSR #2371

Open
sandeepahuja-stack opened this issue Mar 16, 2023 · 7 comments
Labels

Comments

@sandeepahuja-stack
Copy link

Waiting for an action with takeMaybe / take after END is dispatched for SSR

function actionStateUpdate(data){
  return {
   type : 'STATE_UPDATE',
   payload: data
  }
}
function *abc(action){
  const response = yield call(api);
  yield put(actionStateUpdate, response);
  // state is getting updated 
  const state = yield select();
}

function *xyz(action){
  // used both take/takeMaybe
  const wantsToUseActionPayload = yield takeMaybe('STATE_UPDATE');
  console.log("here", wantsToUseActionPayload)
  //in case of take, console is not getting printed
  // in case of takeMayBe  getting => { type: '@@redux-saga/CHANNEL_END' }

  const state = yield select();
  // unable to found updated state 
}

Using Next Js and next redux wrapper
in Get server side props,

store.dispatch(END as any) 
await store.sagaTask.toPromise()
@abduTas
Copy link

abduTas commented Mar 16, 2023

faicing similar issue

@vinii123
Copy link

facing similar issue

@priyam0074
Copy link

@klis87 , can you help on this? as facing the same issue

@neurosnap
Copy link
Member

Greetings! Could you please provide a repo with everything setup so we can better investigate the issue?

@neurosnap neurosnap added the bug label Mar 16, 2023
@sandeepahuja-stack
Copy link
Author

sandeepahuja-stack commented Mar 16, 2023

Hi @neurosnap
Thanks for quick response
unable to provide the repo

But here are my findings
In server side, We have to dispatch the END

store.dispatch(END as any) 
await store.sagaTask.toPromise()

The middleware provides a special action END. If you dispatch the END
action, then all Sagas blocked on a take Effect will be terminated regardless
of the specified pattern. If the terminated Saga has still some forked tasks
which are still running, it will wait for all the child tasks to terminate
before terminating the Task.

as per my observation, here we can't use take then we are using takeMaybe (https://redux-saga.js.org/docs/api/#takemaybepattern)

const wantsToUseActionPayload = yield takeMaybe('STATE_UPDATE');
console.log(wantsToUseActionPayload) // { type: '@@redux-saga/CHANNEL_END' }

Requirement: We need to consume the response in xyz*, which comes from the api in abc*

@sandeepahuja-stack
Copy link
Author

Hi @neurosnap, @Andarist

Could anyone please let us know the ways to handle multiple inter dependent saga on SSR?

@alexya
Copy link

alexya commented Mar 17, 2023

My understanding is: (please correct me if misunderstading)
when calling yield put(actionStateUpdate, response); in the generator abc. the action has been called. If you debug into the reducer, the code such as state.data = action.payload should have been executed. But at this time the store/state may not be applied the latest data even if you complete yield takeMaybe('STATE_UPDATE'); or yield take() call.
I don't know why. It may be related to the event loop of the redux-saga. the put call in the saga is a micro task, the state may not be updated until a macro task is called.
So, you can try to add yield delay(100); or call or setTimeout, etc. before yield select(); to init a macro task to ensure the state is updated (queued micro-tasks will be executed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants