Search code examples
javascriptreactjsreact-nativereduxpolling

Polling in Redux Action


I am trying to pull of polling in one of my redux actions. The following is my action function. It seems to be working, but when the status is no longer "updating" and the data appears, it still runs the loop. Not sure why the stop isn't working.

export const getVisitSummary = () => async (dispatch: Function) => {
  let res = await dispatch({
    type: GET_VISIT_SUMMARY,
    payload: {
      client: 'visitSummary',
      request: {
        method: 'get',
        url: '/visit-summaries'
      }
    }
  });

  const timelineStatus = res.payload.headers['x-timeline-status'];
  const wait = (ms: number) => new Promise(r => setTimeout(r, ms));

  // Not currently updating
  if (timelineStatus !== 'updating') {
    return res;
  }

  // Start polling
  dispatch({ type: START_POLLING });

  while (true) {
    // wait 10 seconds
    await wait(10000);

    res = await dispatch({
      type: GET_VISIT_SUMMARY,
      payload: {
        client: 'visitSummary',
        request: {
          method: 'get',
          url: '/visit-summaries'
        }
      }
    });

    if (timelineStatus !== 'updating') {
      break;
    }
  }

  dispatch({ type: STOP_POLLING });
};

Any help would be useful!


Solution

  • Translating @azundo's comment into an answer:

    export const getVisitSummary = () => async (dispatch: Function) => {
      let res = await dispatch({
        type: GET_VISIT_SUMMARY,
        payload: {
          client: 'visitSummary',
          request: {
            method: 'get',
            url: '/visit-summaries'
          }
        }
      });
    
      /***************************************/
      /*** 1: Change from `const` to `let` ***/
      /***************************************/
      let timelineStatus = res.payload.headers['x-timeline-status'];
      const wait = (ms: number) => new Promise(r => setTimeout(r, ms));
    
      // Not currently updating
      if (timelineStatus !== 'updating') {
        return res;
      }
    
      // Start polling
      dispatch({ type: START_POLLING });
    
      while (true) {
        // wait 10 seconds
        await wait(10000);
    
        res = await dispatch({
          type: GET_VISIT_SUMMARY,
          payload: {
            client: 'visitSummary',
            request: {
              method: 'get',
              url: '/visit-summaries'
            }
          }
        });
        /*********************************************************/
        /*** 2: Use updated `timelineStatus` in if conditional ***/
        /*********************************************************/
        timelineStatus = res.payload.headers['x-timeline-status'];
        if (timelineStatus !== 'updating') {
          break;
        }
      }
    
      dispatch({ type: STOP_POLLING });
    };