0

I'm struggle with the problem and I really need some help. This is my workflow: in onClick() event, I start a action to transfer a data object to reducer and to reduxSaga. When calling API is success, I use put() function in Redux Saga to update state with the response from API. Despite every operation seems to be synchronous, I get old data on the first time I click the button. Here is my code, please see and help me.

Here is my action:

export const clickToDownloadExcelFile = (data) => ({
  type: constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE,
  data,
});

Here is my reducer:

case constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE:
      return { ...state };

    case constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE_SUCCESS:
      return { ...state, dataExcelFile: action.data };

    case constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE_FAILED:
      return { ...state };

Here is my Saga:

function* loadDataExportExcelMerchantList(actions) {
  try {
    const sendData = {
      feeCode: actions.data.feeCode,
      payChannel: actions.data.payChannel,
      typeSource: actions.data.typeSource,
      status: actions.data.status,
      merchantCode: actions.data.merchantCode,
      applyDate: actions.data.applyDate,
      expirationDate: actions.data.expirationDate,
      contract: actions.data.contract,
    };
    const data = yield call(apiFeeMerchantListExportExcel, sendData);
    yield put({
      type: constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE_SUCCESS,
      data,
    });
  } catch (error) {
    yield put({
      type: constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE_FAILED,
    });
  }
}

here is my onClick function:

exportFile = async () => {
    const { clickToDownloadExcelFile, dataSearch, dataExcelFile } = this.props;

    /**/ I start a action right here when I click on the button:**

    await clickToDownloadExcelFile(dataSearch);
     **// I want to get updated data from API in here. have any solution to do it?**
    console.log('dataExcelFile', dataExcelFile);

// at the first time I click on the button, dataExcelFile is null (default value). at the second click , detaExcelFile is a object which I expected it's show from the first click. };

takeLatest(constants.CLICK_TO_EXPORT_EXCEL_MERCHANT_LIST_FILE, loadDataExportExcelMerchantList),

I think because I call action to call Api and Update store exactly in side onClick(function), show after clickToDownLoadExcelFile run and api need some time to response, it keep doing the next code without waiting, so the result of dataExcelFile is doesn't update at the first onClick. do you have any solution for that?

2 Answers2

1

I had same issue and work around by return wanted data from action. And then getting it directly after dispatch

const data = await clickToDownloadExcelFile(dataSearch);

duongital
  • 11
  • 3
0

To wait for api response, use componentDidUpdate method

componentDidUpdate(prevProps){
  if(prevProps.dataExcelFile != this.props.dataExcelFile){
    console.log(this.props.dataExcelFile)
  }
}
  • I know about componentDidUpdate. However, I want to use the dataExcelFile props inside of my onClick function. after I executed the action clickToDownloadExcelFile(), dataExcelFile will be change in store, and I want to use the new value of dataExcelFile at the first click. – Nguyen Ngoc Hai Dec 26 '19 at 09:31
  • That is not possible. Why is `componentDidUpdate` not an option? – Alexander Vidaurre Arroyo Dec 26 '19 at 10:02
  • I'm making an export excel file button. When I click on the button, I will call an API and the API will response to me an array. I need the response data as an input to export an excel file. so I think componentDidUpdate is impossible for this situation. How can I get data from componentDidUpdate to use in onClick function? – Nguyen Ngoc Hai Dec 26 '19 at 10:13
  • Don't use it in `onClick`, use it in `componentDidUpdate`. Call api in `onClick` and export your excel file in `componentDidUpdate` – Alexander Vidaurre Arroyo Dec 26 '19 at 10:25