Search code examples
javascriptreactjsreduxcronnode-schedule

My cron job is always containing the same token values


I'm trying to create a cron job that every minute will make an API request to refresh the session. In the request I send refreshToken as request body. The refresh token, I get it from the store. Bellow is my request.

api.actions.js

export const getAccessToken = () => {
  const { refreshToken } = store.getState(); // getting refreshToken from store
  return apiDefaultAction({
    url: ACCESS_TOKEN_URL,
    method: 'POST',
    data: {
      refresh_token: refreshToken,
    },
    onSuccess: apiData => {
      return {
        type: ACCESS_TOKEN_SUCCESS,
        payload: { ...apiData },
      };
    },
  });
};

The request response is a new accessToken and refreshToken. The reducer than updates the store with a new accessToken and refreshToken:

export default (state = initialState, action) => {
  switch (action.type) {
    ...
    case ACCESS_TOKEN_SUCCESS:
      return {
        ...state,
        accessToken: action.payload.accessToken,
        refreshToken: action.payload.refreshToken,
      };
  }
};

I initiate the cron job calling this method inside a component:

import schedule from 'node-schedule';

const RUN_EVERY_MINUTE = '0 * * * * *';

export const initiateAccessToken = () => {
  schedule.scheduleJob(RUN_EVERY_MINUTE, () => {
    store.dispatch(getAccessToken());
  });
};

However when the requests are happening every minute, the refreshToken is always the same, from the first state. First request receives 200, the rest of the requests are not passing because the refreshToken is not having the updated value from the store and it is expired.

I checked the states before and after the request redux is updating the refreshToken values after the request, but in the cron job is always having the same token. Any ideas why this is happening?

UPDATE

I tried bellow example and the button value isn't changing as well:|

import React from 'react';
import schedule from 'node-schedule';

const RUN_EVERY_10_SEC = '0,10 * * * * *';

const TestComponent = () => {
  let value = 0;
  schedule.scheduleJob(RUN_EVERY_10_SEC, () => {
    value += 1;
  });
  const Button = <button>{value}</button>;
  return <div>{Button}</div>;
};

export default TestComponent;

Solution

  • The reason, I believe, is because your node-schedule code saves a reference to your arbitrary function when you first run it. That means it'll always keep a reference to the store in its initial state and it explains why you're not seeing the update.

    Probably the best solution is to pass the store as a dependency on the function:

    import schedule from 'node-schedule';
    
    const RUN_EVERY_MINUTE = '0 * * * * *';
    
    export const initiateAccessToken = (store) => {
      schedule.scheduleJob(RUN_EVERY_MINUTE, () => {
        store.dispatch(getAccessToken());
      });
    };
    

    This way your function would always have a new and updated reference to your store.