anlogg
anlogg

Reputation: 1090

Pass payload from one saga to another saga

I need to pass payload from fromSaga to toSaga. The problem is it seems that toSaga does not get the payload. However, if I dispatch an action via useEffect, toSaga gets the payload. My observation is that, if you dispatch an action from fromSaga it skips the action creator and goes directly to toSaga. As a result, no payload is sent to toSaga. Here's the real code:

const fetchTokens = function*(action: any) {
    try {
        const userCreds: any = toSnakeCase(action.payload) // action.payload is undefined here
        const response: any = yield call(fetchTokensApi, userCreds)

        if (response.status === 200) {
            const data: any = response.data.data
            const tokens: Tokens = {
               accessToken: data.access_token,
               refreshToken: data.refresh_token,
               expiry: extractExpiry(data.access_token),
           }
           yield put({ type: types.FETCH_TOKENS_SUCCESS, tokens})
       }
    } catch (error) {
        yield put({ type: types.FETCH_TOKENS_FAILURE, error })
    }
}

export const fetchTokensSaga = function*() {
   yield takeLatest(types.FETCH_TOKENS, fetchTokens)
}

const validateAccessToken = function*() {
    try {
        const tokens: Tokens = yield select(tokensSelector)

        if (!tokens) {
            yield put({ type: types.FETCH_TOKENS, USER_CREDS })
        }
    } catch (error) {
        yield put({ type: types.FETCH_TOKENS_FAILURE, error })
    }
}

In validateAccessToken, fetchTokensSaga is called via:

yield put({ type: types.FETCH_TOKENS, USER_CREDS })

fetchTokens should then get the USER_CREDS. However, it's not the case as payload is always undefined. What should I do so fetchTokens gets the USER_CREDS payload?

Upvotes: 1

Views: 1159

Answers (2)

azundo
azundo

Reputation: 6052

You're directly dispatching a raw object, not using an action creator, so you need to put USER_CREDS under the payload key:

yield put({ type: types.FETCH_TOKENS, payload: USER_CREDS })

If you have an action creator like

function fetchTokensActionCreator(userCreds) {
  return {
    type: types.FETCH_TOKENS,
    payload: userCreds,
  };
}

you can instead do yield put(fetchTokensActionCreator(USER_CREDS));

Upvotes: 2

Joseph D.
Joseph D.

Reputation: 12174

You should have a payload key when dispatching as you are using action.payload within fetchTokens().

yield put({
  type: types.FETCH_TOKENS,
  payload: USER_CREDS // add payload
})

Upvotes: 1

Related Questions