2

I am trying to update a value from an array object and object. my sample code is below. Not getting the result as I expected. It would be nice if someone can help?

    let array = [
        {   
            id:"01",
            "name": {
                "value": "jaison",
                "error": null
            },
            "email": {
                "value": "[email protected]",
                "error": null
            }
        },
        {
            id:"02",
            "name": {
                "value": "jaison 1",
                "error": null
            },
            "email": {
                "value": "[email protected]",
                "error": null
            }
        }
    ];

    this.state{
        data:array
    }

    //This two data getting a from a form
    const key = "02";
    const editedData = {name:"updated jaison 1", email:"[email protected]"}

    const newData = [...this.state.data];

    const index = newData.findIndex(item => key === item.id);

    let item = newData[index];

    //Working as expcted 
    console.log('1', item);

    Object.keys(editedData).forEach(function (key) {
      item[key] = editedData[key];
    });

    //Working as expcted 
    console.log('2', item);

    this.setState({ data: [...this.state.data, item]}, () => {
        //Not Working as expcted 
        console.log(this.state.data);
    });

    Expected result
   let array = [
    {   
        id:"01",
        "name": {
            "value": "jaison",
            "error": null
        },
        "email": {
            "value": "[email protected]",
            "error": null
        }
    },
    {
        id:"02",
        "name": {
            "value": "updated jaison 1",
            "error": null
        },
        "email": {
            "value": "[email protected]",
            "error": null
        }
    }
];
4
  • 1
    You're getting the index of the item you need to replace, but you're not overwriting the data declared in editedData which is unused. Commented May 13, 2019 at 8:01
  • You can directly assign value because you have index right this.state.data[2].name.value = "updated jaison 1"; this.state.data[2].email.value ="[email protected]" if you don't know the index that could be different case. hope it works Commented May 13, 2019 at 8:04
  • Object.keys(editedData).forEach(function (key) { item[key] = editedData[key]; }); this is the code I am trying to overwrite or update the data because I can not blindly overnight the data due to a different format Commented May 13, 2019 at 8:05
  • @adiga Answer working for me, any more shortest answers are welcome! Commented May 13, 2019 at 9:54

3 Answers 3

3

When you update item[key] inside the forEach, it just updates name and email with a string values. Also, it mutates the state

Instead, you could loop throguh editedData object update the clone of that specific index. Use the spread syntax to keep error and other properties as it is and update only the value property. Then update the index of the cloned data array and call setState like this:

const key = "02",
      editedData = { name: "updated jaison 2", email: "[email protected]" },
      data = [...this.state.data],
      index = data.findIndex(item => key === item.id),
      updatedData = { ...data[index] };

// loop through and update only the keys you need 
for(const key in editedData) {
  updatedData[key] = { ...updatedData[key], value: editedData[key] }
}

data[index] = updatedData;

this.setState({ data })
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the answer, You are almost there. But 2 things missing. after updated the array disappeared the properties other than the edited one form the first level of the object. Also, I can not give error: null manually for the inner object becouse there is probability to have some more properties there, so can we use a spread operator(...restProps)?
@Jaison updated the answer. Please try it and let me know
Thanks, dear, it's working perfectly what I am looking for, Thanks again.
1

Instead of finding the index and using a forEach to loop over the array, I'd do something like:

const updatedArray = newData.map(item => {
   // if editedData has a key attribute:
   if (item.id === editedData.key) {
       return editedData; //you'd need to add a key attribute to the data
   } else {
       return item;
   }
});
this.setState({data: updatedArray});

1 Comment

Thanks for the quick answer, request you to have a detailed understanding of my question and expected data structure.
0

You can just use map:

   let array = [
        {   
            id:"01",
            "name": {
                "value": "jaison",
                "error": null
            },
            "email": {
                "value": "[email protected]",
                "error": null
            }
        },
        {
            id:"02",
            "name": {
                "value": "jaison 1",
                "error": null
            },
            "email": {
                "value": "[email protected]",
                "error": null
            }
        }
    ];

    const key = "02";

    const updated = array.map(item => {
        if (item.id === key) {
            return {id: key, name:"updated jaison 1", email:"[email protected]"}
        }
        return item;
    });

setState({data: updated});

1 Comment

Thanks for the quick answer, request you to have a detailed understanding of my question and expected data structure.

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.