1

I have a form that is built in with React with react-hook-form that allows users to add dynamic steps using the useFieldArray method which comes with react-hook-form.

My problem is that how can I compare the original data that was passed into the form with the new edited data so I can make the corresponding changes to my backend? Here is an example of the original data:

{
  "id": "1",
  "name": "Recipe Name",
  "method": [ {id:1, method: "method 1", recipesId:  1} , {id:2, method: "method 2", recipesId:  1}],
  "ingredients": [{id:1, ingredient: "ingredient 1", recipesId:  1} , {id:2, ingredient: "ingredient 2", recipesId:  1}]
}

Then the user makes the following changes:

{
  "id": "1",
  "name": "Recipe Name Example",
  "method": [ {id:1, method: "method 1 example", recipesId:  1} , {id:3, method: "method 3", recipesId:  1}],
  "ingredients": [{id:2, ingredient: "ingredient 2 change", recipesId:  1}]
}

So the following has been done:

  1. UPDATE - The name has been changed.

The method array:

  1. UPDATE - The method of id 1 has been changed from "method 1" to "method 1 example"
  2. DELETE - The method with id 2 has been deleted
  3. INSERT - Method 3 has now been added.

The ingredients array:

  1. DELETE - The first ingredient with id 1 has been deleted
  2. UPDATE - The ingredient with id 2 has updated the ingredient from "ingredient 2" to "ingredient 2 change"

Should the changes be in a new object to show changes or individual Insert, Update and Delete arrays/objects?

Thankyou.

Hallidayo
  • 31
  • 7

1 Answers1

0

Loop through the fields and compare to original

Basically...

On view load:

// Make a clean clone of the original data, otherwise the original object may mutate when you update the form!

// This is the modern way; clean clone
this.form = structuredClone(this.theOriginalData)

// Older way (esp for NodeJS pre-v17):
//this.form = JSON.parse(JSON.stringify(this.theOriginalData))

On form update:

Assuming a properly-made reactive form template, your form data object (e.g. this.form) should auto-update and thus always reflect the form state.

On form submit:

let changes = {}

Object.keys(this.form).forEach( key => {
    // Use stringified values for accurate comparison. This is important when comparing arrays.
    if (JSON.stringify(this.form[key]) !== JSON.stringify(this.original[key])) {
        changes[key] = this.form[key]
    }
})

console.log("Form changes are %O", changes)

What you pass to your API is dependent on what the back-end wants. Some API's require a full object, some only the changes are fine.

Kalnode
  • 9,386
  • 3
  • 34
  • 62