kambythet
kambythet

Reputation: 716

Adding item to array in child object of a child object via reducer

I apologize if my terminology is incorrect. I am very new to reactjs and react-redux (couple days).

The challenge I am trying to overcome is adding an item in store.order.cart.items. My store structure is as such:

{
    order:
        cart:
            items: [
                {name: "product a"},
                {name: "product b"}
            ]
}

My reducer is as follows:

import ApplicationState from '../application-state';
import { ADD_PRODUCT } from "../constants/action-types";

const initialState = ApplicationState;

const rootReducer = (state = initialState, action) => {

  switch (action.type) {
    case ADD_PRODUCT:
        return {
            ...state, order: {
                ...state.order, cart: {
                    ...state.cart, items: [
                        ...state.items, action.payload
                    ]
                }
            }
        };
    default:
      return state;
  }
};

export default rootReducer;

My action for ADD_PRODUCT is as follows:

import { ADD_PRODUCT } from "../constants/action-types"

export const addProduct = product => ({ type: ADD_PRODUCT, payload: product });

And my action type constants (constants/action-types):

export const ADD_PRODUCT = "ADD_PRODUCT";

When I dispatch my addProduct action (testing this via the browser console: store.dispatch( addProduct({ name: "product c" }) )

I get the following error:

app.js:36995 Uncaught TypeError: Cannot convert undefined or null to object
    at Function.from (/native)
    at _toConsumableArray (app.js:36995)
    at rootReducer (app.js:37009)
    at Object.dispatch (app.js:13839)
    at <anonymous>:1:7

What am I doing wrong? What is the correct way to get the new item added to the order.cart.items array?

Upvotes: 0

Views: 180

Answers (1)

Anthony
Anthony

Reputation: 6482

items: [
  ...state.items, action.payload
]

In this excerpt above, you have attempted to spread ...state.items into the items array, but items is actually at state.order.cart.items;

Similarly:

cart: {
  ...state.cart, 
}

cart is actually at state.order.cart

Deeply nested situations like this are why it's best to flatten your state where possible and use combineReducers(). Alternately you could look at an immutability helper to help with immutably setting deeply nested state

Upvotes: 1

Related Questions