jack volten
jack volten

Reputation: 273

How can i use yield in redux-saga?

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;

Upvotes: 0

Views: 1817

Answers (1)

hendra
hendra

Reputation: 2661

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
}

Upvotes: 1

Related Questions