Search code examples
reactjsobjectfilter

React filter object and change value within child object


I am trying to use filter to make my life easier.

My goal: Change the closeTime.hours of filter openDay(TUESDAY)

I have an array of objects that looks like:

buildHours = [
  {
    "openDay": "MONDAY",
    "openTime": {},
    "closeDay": "MONDAY",
    "closeTime": {
      "hours": 24
    }
  },
  {
    "openDay": "TUESDAY",
    "openTime": {
      "hours": 9
    },
    "closeDay": "TUESDAY",
    "closeTime": {
      "hours": 17
    }
  },
]

How I am doing this right now is removing the "Tuesday" Object using

    const tempObject = buildHours.filter(i => i.openDay !== "TUESDAY"); // Destroy Tues
    const tempHours = buildHours.filter(i => i.openDay === "TUESDAY")[0]; // Save Tues Obj
    tempHours.openTime.hours = e.value; // Change Hour
    tempObject.push(tempHours); // Recombine
    console.log(tempObject);

Then "rebuilding" the "TUESDAY" object and adding it back to the main object. Although it works .. It seems a little convoluted. Isn't there a way I can use a combination of filter() and set closeTime.hours = 17? I have tried 6 ways to Sunday and nothing seems to work.

Is the way I am doing it right now the preferred method? Remove the object, rebuild and combine?

Or is there a more elegant way to change the hours for Tuesday without destroying the object and rebuilding it in the process?


Solution

  • Without knowing the rest of the context, it's hard to say what the "best" way to do this would be... but, generally, I'd use map instead of filter; something like:

    const buildHours = [ /* ... */ ];  // no change to this
    
    const handleHourChange = (e) => {
      return buildHours.map(o => {
        if (o.openDay !== 'TUESDAY') return o;
    
        return {
          ...o,
          openTime: {
            ...o.openTime,
            hours: e.value,
          },
        };
      };
    });
    

    Also - one minor point on your code - instead of using filter to find the Tuesday object, you can use find -

    const tempHours = buildHours.find(i => i.openDay === "TUESDAY");
    

    And even if you did want to use filter and just get the first one, you can use array destructuring:

    const [tempHours] = buildHours.filter(i => i.openDay === "TUESDAY");