stackjlei
stackjlei

Reputation: 10035

Send 2 arguments to react redux middleware instead of just one action

I want to pass in a boolean value as the 2nd argument to my actionCreator which would determine what my middleware dispatches, but how do I give my middleware access to this 2nd argument? Do I have to dispatch an array or object instead of a promise?

export const fetchPokemon = function (pokemonName, booleanValue) {
  return function (dispatch) {
    dispatch({type: 'REQUESTING'})
    const requestURL = `http://pokeapi.co/api/v2/pokemon/${pokemonName}/`
    dispatch(fetch(requestURL))
  }
}

Middleware

const fetchPromiseMiddleware = store => next => action => {
  if (typeof action.then !== 'function') {
    return next(action)
  }
  ...
  return response.json()
  }).then(function (data) {
    if booleanValue {
      store.dispatch(receivePokemon(formatPokemonData(data)))
    } else {
      store.dispatch(fetchPokemonDescription(data.name))
    }
  })
}

Upvotes: 1

Views: 6188

Answers (1)

Benja
Benja

Reputation: 4154

it seems you have answered yourself, the action you dispatch should contain all the relevant data. The simplest option seem to be to add a property (or properties) to your action, as a Promise is already an object.

export const fetchPokemon = function (pokemonName, booleanValue) {
  return function (dispatch) {
    dispatch({type: 'REQUESTING'})
    const requestURL = `http://pokeapi.co/api/v2/pokemon/${pokemonName}/`
    dispatch(Object.assign(fetch(requestURL), {
      someNameForYourBooleanParameter: booleanValue
    })
  }
}

and

const fetchPromiseMiddleware = store => next => action => {
  if (typeof action.then !== 'function') {
    return next(action)
  }
  ...
  return response.json()
  }).then(function (data) {
    if (action.someNameForYourBooleanParameter) {
      store.dispatch(receivePokemon(formatPokemonData(data)))
    } else {
      store.dispatch(fetchPokemonDescription(data.name))
    }
  })
}

If you want to continue this path, I'd recommend to put these values under a .payload property to prevent any collision with members of the Promise class

I'd take this approach further to avoid the multiple actions being dispatched for the same logical action:

export const fetchPokemon = function (pokemonName, booleanValue) {
  return function (dispatch) {
    const requestURL = `http://pokeapi.co/api/v2/pokemon/${pokemonName}/`;
    dispatch({
      type: 'REQUESTING',
      promise: fetch(requestURL),
      payload: {
        someNameForYourBooleanParameter: booleanValue
      }
    })
  }
}

Upvotes: 1

Related Questions