How can i use yield in redux-saga? Code Answer

After receiving the result value of the refresh function, axiosInstace is executed before saving the accesstoken to AsyncStorage, so the updated token cannot be retrieved in axios.js through AsyncStorage.getItem. i want to save accesstoken first in refresh and get acecesstoken in axios.js and send to axiosInstace

How can I solve this problem?

this is my code

(saga.js)

    function getPostAPI(data) {
      return axiosInstace.post('/kakao/getpost', data);
    }


    function* getPost(action) {
      try {
        const result = yield call(getPostAPI, action.data);
        yield put({
          type: GETPOST_SUCCESS,
          data: result.data,
        });
      } catch (err) {
        if (err.response.data === 'jwtEx') {
          yield put({
            type: REFRESH_REQUEST,
            // data: action.data,
          });
          yield put({
            type: GETPOST_REQUEST,
            data: action.data,
          });
        } else {
          yield put({
            type: GETPOST_FAILURE,
            error: err.response.data,
          });
        }
      }
    }


    function refreshAPI() {
      return axiosInstace.post('/kakao/refresh');
    }

    function* refresh() {
      try {
        const result = yield call(refreshAPI);
        yield AsyncStorage.setItem(
          'accesstoken',
          `${result.data.accessToken}`,
          () => {
            // console.log('accesstoken 재발급 저장 완료');
          },
        );
        yield put({
          type: REFRESH_SUCCESS,
          data: result.data,
        });
      } catch (err) {
        yield put({
          type: REFRESH_FAILURE,
          error: err.response.data,
        });
      }
    }

(axios.js)

    AxiosInstance.interceptors.request.use(async (cfg) => {

      const acecesstoken = await AsyncStorage.getItem('accesstoken');
      const refreshtoken = await AsyncStorage.getItem('refreshtoken');

      if (acecesstoken) {
        cfg.headers.Authorization = `Bearer ${acecesstoken}    ${refreshtoken}`;
      }

      return cfg;
    });

    export default AxiosInstance;

Answer

A simple solution would be to call your refresh() generator directly:

function* getPost(action) {
      try {
        const result = yield call(getPostAPI, action.data);
        yield put({
          type: GETPOST_SUCCESS,
          data: result.data,
        });
      } catch (err) {
        if (err.response.data === 'jwtEx') {
          yield call(refresh);
          
          // you could also redispatch the original action
          yield put(action);
        } else {
          yield put({
            type: GETPOST_FAILURE,
            error: err.response.data,
          });
        }
      }
    }

Alternatively your can start a race between REFRESH_SUCCESS and REFRESH_FAILURE:

const { success, failure } = yield race({
    success: take('REFRESH_SUCCESS'),
    failure: take('REFRESH_FAILURE'),
  });

if(success) {
  // continue
} else {
  // handle refresh failure
}

Related Posts

© No Copyrights, All Questions are retrived from public domain.
Tutorial Guruji