Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 326
Hassam Saeed Avatar asked Dec 17 '20 12:12

Hassam Saeed


People also ask

How do I use setTimeout in Saga?

setTimeout(function timeoutFn(){ sagaMiddleware. run(function*() { yield put({type: ANOTHER_WATCHER }); setTimeout(timeoutFn, 5000); }) }, 5000); Note that doing this is like using the spawn effect meaning the new generator is detached and won't be e.g. cancelled when the above generator is cancelled.

How do I use setTimeout in react?

Using setTimeout in React Components We'll call setTimeout inside of the useEffect Hook, which is the equivalent of the componentDidMount lifecycle method in Class components. import React, { useEffect } from 'react'; const App = () => { useEffect(() => { const timer = setTimeout(() => { setCount('Timeout called!'

What is the use of the setTimeout () function?

setTimeout() The global setTimeout() method sets a timer which executes a function or specified piece of code once the timer expires.

Is setTimeout a callback function?

Introduction to JavaScript setTimeout()cb is a callback function to be executed after the timer expires. delay is the time in milliseconds that the timer should wait before executing the callback function.


1 Answers

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));
      }
    }

like image 98
lissettdm Avatar answered Oct 12 '22 01:10

lissettdm