Mateen Kazia
Mateen Kazia

Reputation: 349

Javascript Function: Reduce redundancy of helpers

I have these few helper function that are used to check if the string in the given array is present and if the certain steps are present and then only have the other function fire. The reason I currently have them separated is because arrTours need to be associated with only those arrSteps.

// Handles for manditory action needed by user
const arrTourOver = ['OverviewTour'];
const arrStepOver = [6, 7];
export const handleJoyrideOverview = (
  dispatch: any,
  tour: any,
  index: number
) => {
  arrTourOver.includes(tour?.openTour) &&
    arrStepOver.includes(tour?.stepIndex) &&
    JoyRideDelayContinue(dispatch, tour, tour?.openTour, index);
};

// Handles for manditory action needed by user
const arrTourResize = ['ResizingWidgets'];
const arrStepResize = [0, 1];
export const handleJoyrideResize = (
  dispatch: any,
  tour: any,
  index: number
) => {
  arrTourResize.includes(tour?.openTour) &&
    arrStepResize.includes(tour?.stepIndex) &&
    JoyRideDelayContinue(dispatch, tour, tour?.openTour, index);
};

// Handles for manditory action needed by user
const arrTourDock = ['DockbarFunctions'];
const arrStepDock = [3, 4];
export const handleJoyrideDock = (dispatch: any, tour: any, index: number) => {
  arrTourDock.includes(tour?.openTour) &&
    arrStepDock.includes(tour?.stepIndex) &&
    JoyRideDelayContinue(dispatch, tour, tour?.openTour, index);
};

These are the 3 I currently have but I will be adding a few more I just want to figure out reducing the redundancy before I keep going

this part isn't really needed but I'll put JoyRideDelayContinue function below just in case

export const JoyRideDelayContinue = (
  dispatch: any,
  tour: any,
  tourType: string,
  stepIndex: number
) => {
  setTimeout(() => {
    if (tour && tour.openTour === tourType) {
      dispatch({ type: 'SET_OPEN_TOUR', payload: '' });
      dispatch({
        type: 'PROGRESS_NEXT_OR_PREV',
        payload: { type: tourType, stepIndex: stepIndex }
      });
      setTimeout(
        () => dispatch({ type: 'SET_OPEN_TOUR', payload: tourType }),
        500
      );
    }
  }, 1000);
};

Upvotes: 0

Views: 49

Answers (2)

Alex Wayne
Alex Wayne

Reputation: 187144

I would probably make a handler creator function which returns the functions that will be used.

If the only parts of this logic that change are the array of string literals and the step numbers, then we those become the argument to this function creator.

Something like:

function createHandleJoyrideAction(actions: string[], steps: number[]) {
  return function handleJoyrideAction(dispatch: any, tour: any, index: number) {
    return actions.includes(tour?.openTour) &&
      steps.includes(tour?.stepIndex) &&
      JoyRideDelayContinue(dispatch, tour, tour?.openTour, index)
  }
}

Now you can simply do:

export const handleJoyrideResize = 
  createHandleJoyrideAction(['ResizingWidgets'], [0, 1])

export const handleJoyrideDock = 
  createHandleJoyrideAction(['DockbarFunctions'], [3, 4])

export const handleJoyrideOverview = 
  createHandleJoyrideAction(['OverviewTour'], [6, 7])

Playground


Also, it's worth mentioning, that's a lot of any. I would strongly recommending build out your types a bit better.

Upvotes: 1

Bergi
Bergi

Reputation: 665020

Your functions basically only differ in two places - two variables even. So just write one function and introduce two extra function parameters for them:

const handleJoyride = (
  arrTour: string[],
  arrStep: number[],
  dispatch: DispatchFunction,
  tour: Tour,
  index: number
) => {
  if (arrTour.includes(tour?.openTour) && arrStep.includes(tour?.stepIndex)) {
    JoyRideDelayContinue(dispatch, tour, tour?.openTour, index);
  }
};

This you can call with different parameters. If necessary, provide three wrapper functions that pass the respective constants for the two parameters and forward their arguments for the rest.

Or even make use of currying:

const makeHandleJoyride = (
  arrTour: string[],
  arrStep: number[]
) => (
  dispatch: DispatchFunction,
  tour: Tour,
  index: number
) => {
  if (arrTour.includes(tour?.openTour) && arrStep.includes(tour?.stepIndex)) {
    JoyRideDelayContinue(dispatch, tour, tour?.openTour, index);
  }
};

/** Handles for manditory action needed by user */
export const handleJoyrideOverview = makeHandleJoyride(['OverviewTour'], [6, 7]);

/** Handles for manditory action needed by user */
export const handleJoyrideResize = makeHandleJoyride(['ResizingWidgets'], [0, 1]);

/** Handles for manditory action needed by user */
export const handleJoyrideDock = makeHandleJoyride(['DockbarFunctions'], [3, 4]);

Upvotes: 1

Related Questions