Understanding Watchers in Vue.js
Tags: watchers, vue, javascript
Published: 2020-07-11 15:51:42

In this article, we will take a deep dive into one of the core concepts in Vue.js -- **watchers**.

We will start from scratch and look at what watchers are and then we will go further to look at two properties available within a watcher: **deep** and **handler**.

We will end the lesson by building a simple project where we will connect to an API endpoint and fetch data to our webpage. Of course, we will use **watchers** to get the job done. 

{% youtube nQzc-F1E5_E %}

**Lets's get started**

Open your text editor to code along. I will be using visual studio code. 
Let's begin with the following HTML markup.
![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464283/samples/Screen_Shot_2020-07-11_at_8.10.22_AM_ey3h5t.png)
Then, <a href="https://vuejs.org/v2/guide/installation.html">head over here to get the Vue.js CDN </a>

![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464257/samples/Screen_Shot_2020-07-11_at_8.11.12_AM_rqa6ss.png)

I have included the Vue.js CDN on the project. To test if everything is working fine, I added a property called <kbd>msg</kbd> in the <kbd>data</kbd> object and outputted it on the DOM. Now go to your browser, you should see **hello timothy** printed on the webpage. 

<h2>Understanding Watchers</h2>

In addition to the <kbd>data</kbd> object, the Vue instance accepts other properties such as <i>methods</i>, <i>computed properties</i>, <i>watch</i>, <i>filters</i>, and life cycle hooks such as <i>mounted</i>. 

As the name implies, watchers **watch** for changes in the value of a property that we have already defined in our data object, and **does something** whenever the value of that property changes. They can also watch for changes in the value of a computed property, and do something whenever the value changes.

**Let's see how it works**

![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464259/samples/Screen_Shot_2020-07-11_at_8.20.29_AM_ambahg.png)

I have added a button to the DOM and attached a method to it called <kbd>changeName</kbd> which gets executed whenever the button is clicked. Below the button, there is an empty div that has a **ref** attribute with a value of **name**. The **ref** attribute will be used to access this div inside of the Vue instance instead of using traditional javascript methods like **getElementById**.

![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464258/samples/Screen_Shot_2020-07-11_at_8.17.31_AM_mrmdrb.png)

As you can see, when the button gets clicked, the <kbd>name</kbd> changes from **Timothy Okooboh** to **Julie Peterson**

{% youtube cQAy8q_74VY %}

The next thing we will do is to **watch** for this change and make something happen whenever the value of <kbd>name</kbd> changes.

![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464258/samples/Screen_Shot_2020-07-11_at_8.20.19_AM_kng1ui.png)

So what is happening here?
We added a **watch** object to the Vue instance. Then we gave it a property called **name** which happens to be a function. Within this function, we listened for changes in the value of the **name** property defined inside of the <kbd>data</kbd> object. When a change occurs, we set the innerHTML of the div that has a **ref** value of **name**.

There is one major thing you **MUST** take note of. The **name** property within the **watch** object MUST BE CALLED **name** and nothing else. Why? you may ask. Well, that is because we are watching for changes in the value of **name**. If we had an **email** property within the <kbd>data</kbd> object and wanted to watch for it, then we would have called the watcher **email** and nothing else.

{% youtube DgLJ2rOPbtU %}

Also, the watcher takes two parameters, the first is the **new value** of the property we are watching. The second parameter is the **old value** of the property we are watching.

<h2>Understanding the handler method</h2>
In our code above, the watcher **name** was declared as a function. But it can actually be declared as an object. When declared as an object, the watcher can take three properties namely a **handler function**, and two booleans **deep** and **immediate**. For the sake of this article, we will focus on the handler function and deep.

![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464301/samples/Screen_Shot_2020-07-11_at_8.25.13_AM_c9tfpp.png)

As you can see in the code above, the **handler** function basically holds the logic that should get executed whenever the value of the property that we are watching for changes. 

Head over to your browser, you should still see that the code works as before.

**What about deep?**
If you understand **deep**, then your knowledge of watchers will be on a new level.

Basically, you use **deep** when watching for changes in the value of items inside an array, or changes in the value of properties inside an object. You will need to set **deep** to **true** in order to tell Vue.js to inspect the contents of arrays and objects.

**Let's see how it works**

![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464305/samples/Screen_Shot_2020-07-11_at_10.45.31_AM_fy3ycg.png)

Before I explain what is going on, let's see the Vue instance.

![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464303/samples/Screen_Shot_2020-07-11_at_10.46.21_AM_qdwttp.png)

We have an array called **fruits**. Then we take the value of the user's input and use it to replace the first item in the array. We then watch for this change and try to render **"the first fruit has changed"** to the DOM

{% youtube -C9J1jT222s %}

As you can see, we successfully changed the value of the first item in the array **but the action inside the watcher failed to execute**. This can be solved by setting **deep** to **true** like so 
![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464338/samples/Screen_Shot_2020-07-11_at_10.51.32_AM_vczxvi.png)

Now if you view it on your browser, you will see that Vue.js can now inspect our array and execute the action stated in our watcher.
{% youtube h_-mb70Wuh8 %}

<h2>Finally, let's build a simple project</h2>
We are going to connect to the **yes/no** API. The way it will work is that our users will type a question inside an input field. Then we will **watch** for changes in the value of the input field and send a **GET** request to the API endpoint. Then we will display the result on the webpage. But before sending the request, we will execute a simple validation -- we will check if the user's question ends with a question mark.

Enough of the talk. Let's see how it works.

We will use **axios** for sending the http request. <a href="https://cdnjs.com/libraries/axios"> Head over here to get the axios CDN</a>
![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464340/samples/Screen_Shot_2020-07-11_at_11.00.41_AM_juh2gz.png)

This is the template markup
![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464341/samples/Screen_Shot_2020-07-11_at_11.37.24_AM_akrwfb.png)

This is the data object
![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464340/samples/Screen_Shot_2020-07-11_at_11.37.54_AM_fsgdpg.png)

This is the method that will send the **GET** request**
![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464342/samples/Screen_Shot_2020-07-11_at_11.38.04_AM_dxzgzr.png)

Then this is our **watcher** 
![code](https://res.cloudinary.com/health-hub-content-creation-and-software-development/image/upload/v1594464343/samples/Screen_Shot_2020-07-11_at_11.38.12_AM_whv2om.png)

Our **watcher** first validates the user's request to check if it ends with a question mark. If the validation passes, it calls the <kbd>getResult</kbd> method after 5 seconds.

{% youtube nQzc-F1E5_E %}

**THANKS FOR READING**. I hope that you learned something. Kindly leave your comments/questions below.