0

I'm getting a hard time adding an object to an array inside a JSON object. This is my state:

const DATA = 
{

 data: [

{
  id: 1,
  routeName: 'my 2 route',
  origin: 'Tel Aviv',
  destination: 'Netanya',
  date: '25-01-2021',
  km: '60',
  stops: [
    {
      id: 0,
      address: 'test',
      lat: '32.0853',
      lon: '34.7818',
      customerName: 'test',
      tel: '00000',
    },
    {
      id: 1,
      address: 'adddress',
      lat: '32.0853',
      lon: '34.7818',
      customerName: 'test',
      tel: '00000',

    }
  ],
},
{
  id: 2,
  routeName: 'my second route',
  origin: 'Holon',
  destination: 'Hadera',
  date: '12-02-2021',
  km: '70',
  stops: [
    {
      id: 0,
      address: 'address0',
      lat: '32.0853',
      lon: '34.7818',
      customerName: 'customer0',
      tel: '00000000',
    },
    {
      id: 1,
      address: 'address1',
      lat: '32.0853',
      lon: '34.7818',
      customerName: 'customer1',
      tel: '00000000',
    },
  ],
},


 ],
}

I don't know how to write the reducer, tried few ways but the state doesn't change. My reducer gets the route id + stop to add this route. I will be happy for some help here :)

2
  • More detail would be helpful. I am guessing that you are saying you are trying to add another object to the stops array??? Generally your reducer will need to supply a new object with a new array, not mutate the existing one. Commented Feb 13, 2021 at 15:12
  • Yes, this is exactly what I'm trying to do. What details could with here? My biggest problem is that I don't know to how to push this object to this array. Commented Feb 13, 2021 at 15:13

2 Answers 2

1

You'll need to find the parent route using the route's id, and then you'll need to create a new stops array by spreading, and adding the new stop.

You can use Array.findIndex() to find the actual route, and the slice the array, and update the route. However, another simple option is to map the data's routes, and update the route with the matching id.

const routeReducer = (state, { type, payload: { routeId, stop } }) => {
  switch (type) {
    case 'ADD_STOP':
      return {
        ...state,
        data: state.data.map(route => route.id === routeId ? {
          ...route,
          stops: [...route.stops, stop]
        } : route)
      }
  }
}

Usually in redux it's better to normalize the state, which makes it easier to update single items.

Sign up to request clarification or add additional context in comments.

Comments

0

You could have a reducer that did something like this:

const updateItemInArray = (array, itemId, updateItemCallback) => {
    return array.map(item => {

        if (item.id !== itemId) return item;

        // Use the provided callback to create an updated item
        return updateItemCallback(item);
    });
};

const data = (state = [], action) => {
    switch (action.type) {
        case 'ADD_STOP_SUCCESS':
            return updateItemInArray(state, action.payload.routeId, (item) => ({...item, stops: [...item.stops, action.payload.stop]}))
        default: return state;
    }
}

When the action.type 'ADD_STOP_SUCCESS' is called the payload of the action would contain the new stop object you are wanting to add to the state.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.