user12763413
user12763413

Reputation: 1349

watch not getting all in Vue

<template>
 <v-form :model='agency'>
  <v-layout row wrap>
    <v-flex xs12 sm12 lg12 >
      <v-layout row wrap>
       <v-flex xs12 md12 class="add-col-padding-right">
        <v-radio-group
         v-model="agency.location"
         :mandatory="true"
         label="Please select one of the options below">
           <v-radio label="NYC" value="nyc"></v-radio>
           <v-radio label="SAN JOSE" value="san_jose"></v-radio>
        </v-radio-group>
       </v-flex>
      </v-layout>
    </v-flex>
  </v-layout> 
 </v-form>
</template>   

<script>

  export default {

   data: function () {
    return {
      agency: {
        id: '',
        name: '',
        location: '',
        contacts: {
          name: '',
          number: '',
          address: ''
        }
      },
      final_location_contact: {
       name: '',
       number: '',
       address: ''
      }
    }
   }
   watch: {
    agency: {
      handler(val){
       if (this.agency.location === "nyc") {
        this.final_location_contact = this.agency.contacts;
       }
    }
   },
   created: function() {
    this.fetchAgency();
   },
   method: {
    fetchAgency() {
      this.$axios.get('/agency.json')
      .then(response => {
        if (Object.keys(response.data).length > 0) {
          this.agency = response.data;
        }
      }).
      then(() => {
      });
    },
   }
  }
</script>

The issue I am facing here is when the page loads, and the fetchAgency method runs and I am able to get the agency data. When I select first option from the radio button, then I am able to assign the value agency.contacts values to final_location_contact. But the issue arrises when I first select the San Jose Radio button option and after that I select nyc radio button then I am not able to assign the value agency.contacts values to final_location_contact as I checked using debugger the value of agency.contacts is empty. But it not empty if I select nyc the first time. Any Idea where could be the issue?

'agency.location': {
  handler (newValue, oldValue) {
    if (newValue === "nyc") {
      this.final_location_contact = this.agency.contacts;
    }
    else {
      this.final_location_contact.name: '',
      this.final_location_contact.number: '',
      this.final_location_contact.address: ''
    }
  }
 }

Upvotes: 0

Views: 67

Answers (3)

user12763413
user12763413

Reputation: 1349

watch: {
 'agency.location': {
      handler (newValue, oldValue) {
        var new_location = {}
        if (newValue === "nyc") {
          new_location = this.agency.contacts;
        }
        else {
          new_location = {
            name: '',
            number: '',
            address: ''
          }
        }
        this.final_location_contact = new_location;
      }
    }
}

this is how I made it work.

Upvotes: 0

Kamil Bęben
Kamil Bęben

Reputation: 1172

As Jacob said, the watcher is not being triggered because agency itself was not changed.

In the comment i've suggested to use deep watcher, but that's not the best approach. You can listen specifically to changes made on 'agency.location' this way:

watch: {
  'agency.location': {
    handler (newValue, oldValue) {
      // this will be triggered every time `agency.location` is changed
    }
  }
}

This is better than deep watching, which would look like this

watch: {
  deep: true,
  agency (newValue, oldValue) {
    // logic
  } 
}

because deep watcher will be triggered any time either agency or any of it's properties will change.

Here is fiddle which demonstrates the difference and how it's implemented (make sure to open the console).

If the watcher not being triggered is the issue here, then no changes to the model / template is necessary.

Upvotes: 1

Jacob
Jacob

Reputation: 1840

The problem you're running into, is that in the eyes of JavaScript, you aren't changing the value of agency when you change agency.location. In the eyes of the language agency is still the same object, no matter what you do to its properties. That watcher is waiting for a change to the entire object, like agency = {different: "object"} what I would recommend you do is break out location to its own top level property and adjust that, like this:

data: function () {
    return {
      location: '',
      agency: {
        id: '',
        name: '',
        location: '',
        contacts: {
          name: '',
          number: '',
          address: ''
        }
      },
      final_location_contact: {
       name: '',
       number: '',
       address: ''
      }
    }
   }

That way, you can set a watcher on that property like so:

watch: {
    location: function(val) {
      this.agency.location = val
       if (val === "nyc") {
        this.final_location_contact = this.agency.contacts;
       }
    }
   },

Upvotes: 1

Related Questions