0

I have an array of objects

[
  {
    "0": {
      "title": "Jessica Simpson",
      "id": "324352342323432",
      "url": "image-url.jpg",
      "colourScheme": "",
      "type": "",
      "enabledUnits": ""
    },
    "1": {
      "title": "Bill Murray",
      "id": "5qocDvdm9XETFz33p725IG",
      "url": "image-url.jpg",
      "colourScheme": "",
      "type": "",
      "enabledUnits": ""
    },
  }
]

I'm attempting to add update the colourScheme value inside the object via an onChange event handler.

OnChangeHandler

  const createOnChangeHandler = (floorPlan: FloorPlan, property: 'colourScheme' | 'type') => (
    e: React.ChangeEvent<HTMLInputElement>
  ) => {

      console.log(( e.target.value ))
      const itemList = floorPlans.concat();
      const index = itemList.findIndex((i) => i.id === floorPlan.id);
      itemList.splice(index, 1, {...floorPlans, [property]: e.target.value});
  };

But it's being added outside the object. For example... notice "colourScheme": "Black" is outside.

  {
    "0": {
      "title": "Angeline Espaze",
      "id": "5qocDvdm9XETFz33p725IG",
      "url": "image-url.jpg",
      "colourScheme": "",
      "type": "",
      "enabledUnits": ""
    },
    "colourScheme": "Black"

  }
]

Where i would like

[
  {
    "0": {
      "title": "Angeline Espaze",
      "id": "5qocDvdm9XETFz33p725IG",
      "url": "image-url.jpg",
      "colourScheme": "Black",
      "type": "",
      "enabledUnits": ""
    },
  }
]

I think the issue is with itemList.splice? inside the onChange
1
  • To clarify, the array of objects you have posted, is in fact a single item array with an object with 2 properties 0 & 1.. Commented Sep 29, 2021 at 11:07

2 Answers 2

2

The problem is:

  1. You're spreading the wrong thing into the new object, and

  2. You're not calling a state setter.

I wouldn't use splice for this at all, you can do the object update while copying the array rather than afterward. Instead (see comments):

const createOnChangeHandler = (floorPlan: FloorPlan, property: 'colourScheme' | 'type') => (
    e: React.ChangeEvent<HTMLInputElement>
) => {
    const {value} = e.target;
    // Call the state setter; because we're updating state based on existing state, it's
    // best to use the callback version
    setFloorPlans(floorPlans => {
        // Return a new array with a replaced object
        return floorPlans.map(entry => {
            if (entry.id === floorPlan.id) {
                // Create a replacement object
                return {...entry, [property]: value};
            }
            return entry; // No change to this object
        });
    });
};

That's assuming you're using hooks. If you're using a class component, use this.setState instead:

const createOnChangeHandler = (floorPlan: FloorPlan, property: 'colourScheme' | 'type') => (
    e: React.ChangeEvent<HTMLInputElement>
) => {
    const {value} = e.target;
    // Call the state setter; because we're updating state based on existing state, it's
    // best to use the callback version
    this.setState(({floorPlans}) => {
        // Return a new array with a replaced object
        return {floorPlans: floorPlans.map(entry => {
            if (entry.id === floorPlan.id) {
                // Create a replacement object
                return {...entry, [property]: value};
            }
            return entry; // No change to this object
        }});
    });
};
Sign up to request clarification or add additional context in comments.

Comments

0

Try below code.

 const createOnChangeHandler = (floorPlan: FloorPlan, property: 'colourScheme' | 
  'type') => ( e: React.ChangeEvent<HTMLInputElement>) => {
   
   let lclfloorPlans = [...floorPlans];

   lclfloorPlans.forEach(item => {
   for (var key in item) {
    if (item[key].id === floorPlan.id) {
      item[key][property] = e.target.value;
      break;
    }
  }
});

setFloorPlans(lclfloorPlans); // assign to your state value
};

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.