# Performing A Deep Watch In Vue.js

If you are a vue.js developer like me, you've definitely come across **Watch** (Watchers).
In this tutorial we are going to have look at what a watcher is and how we use **watch** over arrays of object.

## What is watcher?

A Watcher is a useful and special feature provided by VueJs to watch over a component or data property and perform specific actions when the value of the `component` or `data property` is changed. It is the most generic and recommended way to react over a data change in a vue instance.
When we are performing asynchronous operations like calling the API, or dealing with promises, **watcher** is the most recommended way to perform logical operations when data gets changed.

### Basic example of watcher.

In this example, we are converting the user input of the `kilometer` value into miles 



- Let's first prepare our template to display the results inside the `App.vue` file as shown below:

```
<template>
  <div id="app">
    <h1>Basic Example for the <a href="https://vuejs.org/guide/essentials/watchers.html#basic-example" class="watch">watchers</a> in vue.js</h1>

    <label for="km">Enter KM to get the mils:</label>
    <input type="number" id="km" v-model="km">

    <p class="result">Converted Miles: {{miles}}</p>
  </div>
</template>
```

- Now, we have to write the logic to find the miles when the user changed the value of kilometer. Here the watcher comes in play, we have to watch for value of **km** when it's value changed we have to update the **miles** output.


- Enter the following code snipper into the `script` tag: 

```
export default {
  name: "App",
  components: {},
  data () {
    return {
      miles: 0,
      km: 0,
    }
  },
  watch: {
    km (newVal, oldVal) {
      this.miles = (this.km * 0.6214).toFixed(2)
    }
  }
};
```


- In this way, we can use watcher to perform operations when a piece of data changes. [Here](https://codesandbox.io/s/basic-watcher-example-dbko5e?file=/src/App.vue:360-573) is the link for the code that we discussed here.

### Deep watcher over array of objects.


- Let's create a dummy array of objects using the following code snippet:

```
users: [
  { id: 1, name: "shiv" },
  { id: 2, name: "Jhon" },
  { id: 3, name: "Mariya" },
]
```

- Now, we have to create a Vue SFC `User.vue` using the following code:

```
<template>
  <div class="main">
    <p class="id">{{ userData.id }}:</p>
    <div class="left-section">
      <input type="text" v-model="user.name" />
      <p class="display">New Value: {{ newDisplay }}</p>
      <p class="display">Old Value: {{ oldDisplay }}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "User",
  props: {
    userData: {
      type: Object,
      default: () => {},
    },
  },
  data: () => {
    return {
      user: null,
      newDisplay: "",
      oldDisplay: "",
    };
  },
  created() {
    this.user = JSON.parse(JSON.stringify(this.userData));
    console.log(this.user);
  },
  watch: {
    "user.name": function (newVal, oldVal) {
      this.newDisplay = newVal;
      this.oldDisplay = oldVal;
    },
  },
};
</script>
```


- After creating the `User.vue`, we have to `import` it in the `App.vue` file and pass **users** as a `prop`. In `User.vue`, we are using **watcher** over the value which is changing and we are also using `user.name` property instead of `user` so that vue can detect the change happening to `user.name`. Because of this, we will not be changing the user object but we will be changing the `name` key inside the   **user  ** object.


- Now, add the following lines in the `App.vue` file: 

```
<template>
  <div id="app">
    <user v-for="(item, index) in users" :key="index" :userData="item" />
  </div>
</template>

<script>
import User from "./components/User";
export default {
  name: "App",
  components: { User },
  data() {
    return {
      users: [
        { id: 1, name: "shiv" },
        { id: 2, name: "Jhon" },
        { id: 3, name: "Mariya" },
      ],
    };
  },
};
</script>
```


- Now whenever the user is changing the value of the input field, we can see that the value of the below paragraph is also changing.

There is another way to perform Deep watch over objects or an array of a object.

### Second way to perform deep watch:

- Add the following lines into your console:

```
<script>
export default {
  props: {
    userData: {
      type: Object,
      default: () => {},
    },
},
  watch: {
    user: {
    handler:function(newVal) {
      console.log("new Value is " + newVal)
    },
     deep:true
    },

  }
};
</script>
```
- In this way, we only get the `new value` or you can say the updated value of the property. We are not going to get the **old value**.

> **NOTE:** If you also want to run your **watcher** at the time of initialization, you have to add `immediate: true` inside your watcher like this:

```
watch: {
user: {
    immediate: true,
    handler:function(newVal) {
      console.log("new Value is " + newVal)
    },
     deep:true
    },
},
```

You can play with the deep watcher code [here](https://codesandbox.io/s/deep-watcher-ev3jhc)

### Conclusion

By this using the methods mentioned in this article, we can perform a **deep watch** inside vue.js over an array of objects. Sometimes it's hard to detect changes in 2-3 level nested objects or data. Insuch cased twe can use deep watcher to do our task.
I hope this helps you understand the concepts of **deep watcher** in VueJs.

Thanks 🙏 

