Search code examples
javascriptreactjsreact-reduxredux-sagasaga

setTimeout function in saga React.js


I just want to hide Undo Button in UI after 5 seconds. Here is my code:

Saga.js

function* updateActionListingsSaga({ payload }) {
  try {
    const res = yield call(updateUnpublishedListingsById, payload);
    let unpublishedListings = yield select(UnpublishedListings);
    if (res) {
      const row = unpublishedListings.listingsData.results.find(data => data.id === res.ids[0])
      if (row) {
        row.review_status = payload.review_status
        row.isUndoEnabled = true;
        yield setTimeout(() => {row.isUndoEnabled = false}, 5000)
      }
    }
    
    yield put(updateActionListingSuccess());
  } catch (error) {
    yield put(apiError(error.error || error.message || error));
  }
}

Index.js

item?.isUndoEnabled && (
  <ConfirmDialogBtn
    button={{
      color: 'primary',
      title: 'Undo',
      icon: 'bx bx-undo',
    }}
    msg="Set this Listing as Undo"
    onConfirm={() => handleUpdateListing(item?.id, 'pending')}
  />
)

I am retrieving a particular row set an Undo Button by appending row.isUndoEnabled= true property and After 5 seconds delay I just set it to row.isUndoEnabled= false.

Actual Output: Property is set to True but doesn't hide the Button

Expected Output: Hide the Button

Hope for the best Answer. Thank you


Solution

  • The button is not hiding because updateActionListingSuccess function is called before timeout callback is executed. I recommend you:

    1. Wrap the timeout function inside a Promise and wait until it finished.
    2. Call updateActionListingSuccess just after the promise is resolved.
        function* updateActionListingsSaga({ payload }) {
          try {
            const res = yield call(updateUnpublishedListingsById, payload);
            let unpublishedListings = yield select(UnpublishedListings);
            let row = null;
            if (res) {
              row = unpublishedListings.listingsData.results.find(
                data => data.id === res.ids[0]
              );
              if (row) {
                row.review_status = payload.review_status;
                row.isUndoEnabled = true;
              }
            }
            yield put(updateActionListingSuccess());
            if (row) {
              yield new Promise(resolve =>
                setTimeout(() => {
                  row.isUndoEnabled = false;
                  resolve();
                }, 5000)
              );
            }
            yield put(updateActionListingSuccess()); // update again
          } catch (error) {
            yield put(apiError(error.error || error.message || error));
          }
        }