3

I am trying to update an array of objects in the redux state,

cars redux state

cars:  [
  {
    _id:"5b61b782719613486cdda7ec",
    car: "BMW",
    year: '2015'
   },
   {
      _id:"5b61b782719613486cdda7e1",
      car: "Toyota",
      year: '2015'
    },
    {
      _id:"5b61b782719613486cdda7e2",
      car: "Honda",
      year: '2015'
    },
    {
      _id:"5b61b782719613486cdda7e3",
      car: "Audi",
      year: '2015'
    }
 ]

action.payload array

 action.payload :      
   [
    {
      _id:"5b61b782719613486cdda7ec",
      car: "BMW",
      year: '2019'
    },
    {
      _id:"5b61b782719613486cdda7e3",
      car: "Audi",
      year: '2019'
    }
  ]


case UPDATE_CARS:
  const updatedCars = state.cars.map((car) => {
  action.payload.forEach((newCars, index) => {
    if (car._id !== newCars._id) {
      //This is not the item we care about, keep it as is
      return car;
    } else {
      //Otherwise, this is the one we want to return an updated value
      return { ...car, ...newCars };
    }
  });
});

return {
  ...state,
  cars: updatedCars,
  loading: false
};

As you can see I am trying to update multiple items in the redux array only if item exists in the redux state.

What am I doing wrong? Any suggestions?

0

2 Answers 2

7

Another alternative:

const updatedCars = state.cars.map( car => {
  const found = action.payload.find( el => el._id === car._id );
  return found ? found : car;
});

forEach does not return anything, it just executes the given function for the current element. So, for the situations like that map is your friend.

Even there is a shorter and nicer version which @Luke M Willis provided in the comments:

const updatedCars =
    state.cars.map(car => action.payload.find(el => el._id === car._id) || car);
Sign up to request clarification or add additional context in comments.

3 Comments

@publicArt33 So you wanted the return value to be an array. not as object which I gave.. got it.
You can shorten this to state.cars.map(car => action.payload.find(el => el._id === car._id) || car)
Thank you @LukeMWillis, this is a really nice logic. I should remember this as a learner. Also, I've updated my answer and added your solution.
0

I'll filter out the cars from state, which are present in action.payload. Then I'll merge the action.payload, and filtered state like below.

case UPDATE_CARS:
  const updatedCarIds = action.payload.map(o => o.id);
  const notUpdatedCars = state.cars.filters(car => !updatedCarIds.includes(car.id))
  return [...notUpdatedCars, ...action.payload]

2 Comments

Thanks @Arup ! Btw, there is a small inaccuracy in your code const notUpdatedCars = state.cars.filter(car => !updatedCardIds.CarIds.includes(car.id))
@publicArt33 What is that?

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.