I have a parent component that is passing down some API data to a child component in order to pre-populate some input fields. When the user changes some of this data on the child component, that child component emits the data back to the parent where we will process it for server submission on user form submit.
To handle the updates for processing, I am sending the child data back as an object which the parent stores in an array (array of objects). This array is what I am sending to the server for processing.
I am struggling with how to update object properties in an array of objects.
Codesandbox: https://codesandbox.io/s/romantic-mestorf-yc0i1h?file=/src/components/Parent.vue
Let me explain in detail. I have 3 components:
<App>
<Parent>
<Child />
</Parent>
</App>
App.vue:
<template>
<div id="app">
<form @submit.prevent="submitForm()">
<Parent
:localShortNames="formValues.localShortNames"
@save-form-data="saveFormData"
/>
<button type="submit">Submit</button>
</form>
</div>
</template>
<script>
import Parent from "./components/Parent.vue";
import data from "./assets/data.json"; // <--- will be an actual API request
export default {
components: {
Parent,
},
data() {
return {
formValues: {
localShortNames: data,
},
};
},
methods: {
saveFormData(x) {
// TO DO
},
submitForm() {
// TO DO: save data to server
},
},
};
</script>
Parent.vue:
<template>
<div>
<h5>List of Data</h5>
<Child
v-for="item in localShortNames"
:key="item.localSnameID"
:localShortName="item"
@save-form-data="saveFormData"
/>
</div>
</template>
<script>
import Child from "./Child.vue";
export default {
props: {
localShortNames: {
type: Array,
},
},
components: {
Child,
},
data() {
return {
newLocalShortNamesArr: this.localShortNames,
};
},
methods: {
saveFormData(x) {
let elementId = (el) => el.localSnameID === x.localSnameID;
const newArr = this.newLocalShortNamesArr.map((obj) => {
if (elementId) {
// I need to update the existing object in newLocalShortNamesArr with updated user submitted properties
// ...
} else {
// item does not exist, lets push it to newLocalShortNamesArr
// TO DO LATER: create "add new data" button for adding new objects to array
},
},
},
},
}
</script>
Child.vue:
<template>
<div>
<label for="name-input">Name:</label>
<input
type="text"
id="name-input"
v-model="formValues.name"
@input="$emit('save-form-data', formValues)"
/>
<label for="dialect-input">Dialect:</label>
<input
type="text"
id="dialect-input"
v-model="formValues.iso6393Char3Code"
@input="$emit('save-form-data', formValues)"
/>
</div>
</template>
<script>
export default {
props: {
localShortName: {
type: Object,
},
},
data() {
return {
formValues: {
localSnameID: this.localShortName
? this.localShortName.localSnameID
: null,
name: this.localShortName ? this.localShortName.name : null,
iso6393Char3Code: this.localShortName
? this.localShortName.iso6393Char3Code
: null,
},
};
},
};
</script>
Question: How to handle the update of objects in an array and “overwrite” those properties (name, and iso6393Char3Code) if the same id exists in the original array?
In the parent.vue, I was thinking of doing something like this, but I don’t know:
saveFormData(x) {
// console.log(x);
let elementId = (el) => el.localSnameID === x.localSnameID;
const newArr = this.newLocalShortNamesArr.map((obj) => {
if (elementId) {
// I need to update the existing object in newLocalShortNamesArr with updated user submitted properties
// ...
} else {
// item does not exist, lets push it to newLocalShortNamesArr
// ...
}
});
Would Object.assign be better here vs map()? All I am trying to do is provide an array to the API called localShortNames that contains all the objects whether they have been updated or not. Hope this makes sense!
I have a codesandbox here with the above code: https://codesandbox.io/s/romantic-mestorf-yc0i1h?file=/src/components/Parent.vue

