Christian Todd
Christian Todd

Reputation: 246

Update a single object property in an array of objects based on the current value with redux

Within my state, I have an array of objects that have a few descriptive properties, a quantity, and a unique id. The data within this object comes back from an API response, and within my action creator, I check the state to see if it exists already and if so dispatch an increment action for my reducer. This is what my action creator looks like:

export const getProductDetails = upc => (dispatch, getState) => {
const state = getState();
const products = state.table.products;
if (_find(products, upc) !== undefined) {
  dispatch({ type: INCREMENT_QUANTITY, payload: upc });
} else {
axios
  .post(<--POST TO ENDPOINT-->) }
  })
  .then(res => {
    dispatch({ type: POST_UPC, payload: res.data });
  })
  .catch(err => {
    errorHandler(dispatch, err.response, AUTH_ERROR);
  });
 }
};

My reducer for this case looks is structured as so:

case INCREMENT_QUANTITY:
  return {
    ...state,
    products: state.products.map(product => {
      action.payload === product.upc
        ? { ...product, quantity: product.quantity + 1 }
        : product;
    })
  };

I based this reducer logic from this this excellent response, but for some reason when the action is dispatched, the duplicate product is overwritten as null instead of incrementing the quantity as expected. I'm still trying to learn redux right now, so forgive my ignorance. Ideally, I'd like to avoid bringing in a library or package just to increment a value. What exactly am I missing within my reducer?

Upvotes: 0

Views: 568

Answers (1)

Andrew Li
Andrew Li

Reputation: 57964

You're not returning anything in your map callback, you're creating a block thus you don't get the intended result. Instead, omit the brackets { … }:

products: state.products.map(product => 
  action.payload === product.upc
    ? { ...product, quantity: product.quantity + 1 }
    : product;
);

This will use arrow function syntax to implicitly return the result of the ternary operator.

Upvotes: 3

Related Questions