nickb84
nickb84

Reputation: 641

vue merge two arrays of objects

I have 2 components:

  1. parent component (vue-bootstrap modal with a vue-bootstrap table)
  2. child component (vue-bootstrap modal with a form)

When I submit the form in the child component I want to push the object to the parent table array and that works! But when I reset the form it also resets the object in the table array and I don't know why. I tried push and concat.

parent variable:

MA02_E_tb // table array [{descr_forn: '',fornitore:'',n_oda:''},{descr_forn: '',fornitore:'',n_oda:''}]      
 data() {
      return {
        form: {
          descr_forn: 'prova',
          fornitore:'prova',
          n_oda:'prova',
      }
    },
  methods: {
      resetModal() {
        this.form.descr_forn = '',
        this.form.fornitore = '',
        this.form.n_oda = '',
      },
      onSubmit: function(evt) {
        evt.preventDefault()
        this.$parent.MA02_E_tb = this.$parent.MA02_E_tb.concat(this.form)
      },

result:

MA02_E_tb = [{descr_forn: 'prova',fornitore:'prova',n_oda:'prova'}]

When I reopen the child modal and I reset the object form with the resetModal method the result is:

MA02_E_tb = [{descr_forn: '',fornitore:'',n_oda:''}]
form = [{descr_forn: '',fornitore:'',n_oda:''}]

Why does it reset MA02_E_tb if it's another variable?

Upvotes: 1

Views: 3531

Answers (1)

skirtle
skirtle

Reputation: 29092

First up, you really, really, really shouldn't be using $parent like that. You should be emitting an event instead. But that isn't what's causing the problem.

The actual problem is that you are passing an object by reference. If you then change that object it will be changed in both places. It doesn't matter what name, identifier or path you use to access it, it's still the same object.

Assuming it is a flat object you can make a shallow copy using the spread operator, ...:

this.$parent.MA02_E_tb = this.$parent.MA02_E_tb.concat({...this.form})

This will create a new object with the same properties as this.form. It is important to realise that this is only a shallow copy. If this.form contained further reference types (i.e. objects, arrays, etc.) then those may need copying as well.

As an event this would be something like:

this.$emit('submit', {...this.form})

You'd then need a suitable @submit listener in the parent template to update the array. The idea here is that only the owner of the data should be allowed to modify it and in this case that array is owned by the parent.

Upvotes: 2

Related Questions