Configuring Vue.js watchers inside a for loop

Exploring the dynamic addition of watchers in Vue.js. The discrepancy between what is desired and what actually happens is demonstrated below in the commented section. As a casual coder, I believe my issue lies more in grasping JavaScript basics rather than Vue itself. Appreciate any help!

new Vue({
    el: '#app',
    data: {
        a: 1,
        b: 2,
        c: 3
    },
    methods: {
        setUpWatchers(array) {
            for (var i in array) {
                var key = array[i];

                this.$watch(key, function(newValue) {
                    console.log(key + ': ' + newValue);

                    //desired output should be:
                    //  a: 4
                    //  b: 5
                    //  c: 6

                    //actual output is currently:
                    //  c: 4
                    //  c: 5
                    //  c: 6

                });
            }
        }
    },
    created() {
        this.setUpWatchers(['a', 'b', 'c']);

        this.a = 4;
        this.b = 5;
        this.c = 6;
    }
});

Answer №1

Indeed, you're right; this situation presents a common javascript "trick".

Variables that are declared with var possess function scope. Therefore, when utilizing var, each and every function declared within your loop (in this case, three functions for $watch) utilize the same variable. As a result, once the loop concludes, it references c.

To rectify this issue, one can declare the variables using let. Unlike var, let offers block scope. Consequently, each function declared within the loop will solely have access to the specific instance of the variable at the exact moment when the function was generated.

Below is an illustration of the corrected code:

new Vue({
    el: '#app',
    data: {
        a: 1,
        b: 2,
        c: 3
    },
    methods: {
        setUpWatchers(array) {
            for (let i in array) {
                let key = array[i];

                this.$watch(key, function(newValue) {
                    console.log(key + ': ' + newValue);
                });
            }
        }
    },
    created() {
        this.setUpWatchers(['a', 'b', 'c']);

        this.a = 4;
        this.b = 5;
        this.c = 6;
    }
});
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f7818292b7c5d9c5d9c1">[email protected]</a>/dist/vue.js"></script>
<div id="app"></div>

In current times, it is advisable to use let or const rather than var as much as possible. Various educational resources detail the distinctions among them.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

AngularJS, the element being referenced by the directive is empty

Currently, I am in the process of transferring a jQuery plugin to AngularJS simply for the enjoyment of it. Previously, when working with jQuery, my focus was on manipulating the DOM using jQuery functions within the plugin loading function. Now that I am ...

Can someone help me uncover the previous URL for login using just JavaScript? I've tried using document.referrer but it's not giving me the

Currently, I am utilizing express with pug templates and pure JavaScript. In order to enhance the user experience of my log in system, I would like to save the URL that someone came to the login page with, so that I can redirect them back to it once they h ...

Do you have any recommendations for a jQuery plugin that can create a sleek horizontal scrolling image gallery?

Recently, I came across the Smooth div scroll plugin developed by Thomas Kahn, and it fits my requirements perfectly. However, I have encountered a bug that seems to be persisting. The issue arises when both mousewheel scroll and touch scroll are enabled s ...

Troubleshooting Problems with Owl Carousel Loading

Having trouble with Owl Carousel loading issue. I've set up my carousel using the Owl Carousel jQuery plugin as guided, but it's showing me an "owl-carousel loading" class added to the DOM (owl-loading). I've tried adding custom styles and J ...

Is hard coding permissions in the frontend considered an effective approach?

I'm in the process of creating an inventory management system that allows admin users to adjust permissions for other employees. Some permissions rely on others to function properly, and I need to display different names for certain permissions on the ...

Incorporate PHP form and display multiple results simultaneously on a webpage with automatic refreshing

I am currently in the process of designing a call management system for a radio station. The layout I have in mind involves having a form displayed in a div on the left side, and the results shown in another div on the right side. There are 6 phone lines a ...

tips for integrating html5 elements with django forms

I am interested in utilizing the following code: # extra.py in yourproject/app/ from django.db.models import FileField from django.forms import forms from django.template.defaultfilters import filesizeformat from django.utils.translation import ugettext_ ...

Is it possible to show a pop-up window containing aggregated data when the jQuery double-click event

How can I create a pop-up window to display aggregated data when the Double-click event is triggered in jQuery? In my code, each questionId has multiple related reasons. When a user clicks or selects a questionId button/event, the selected questionId will ...

Guide on extracting an Array from JSON in a $.ajax response

I received a JSON value that was converted from an array in the AJAX response. {"Text":"Please provide a value","Email":"Please provide a value"} My goal is to extract the response JSON and display it within a div using $(div).html(): Text-Please provid ...

Access the content of each cell in a table using JavaScript

I need help with a scenario involving a table that has 4 rows, where the 4th row contains a textbox. When the "onchange" event of the textbox is activated, I want to retrieve the data from the cells in that specific row and transfer it to another table. It ...

Uniting 2 streams to create a single observable

I am in the process of merging 2 different Observables. The first Observable contains a ShoppingCart class, while the second one holds a list of ShoppingItems. My goal is to map the Observable with shopping cart items (Observable<ShoppingItems) to the i ...

JavaScript popup is no more visible on the webpage

Recently, I implemented a pop-up on my website that used cookies to prevent it from appearing every time a user visited a page. However, after making this change, the pop-up stopped showing altogether. Despite my best efforts in testing, researching, and s ...

Production environment experiences issues with Angular animations

In my MEAN stack application, I started with Sails.js. Everything was working smoothly during development, especially with angular-animate. However, once I changed the Sails environment to production, I encountered issues. Grunt is set up to concatenate a ...

Using Vue JS to showcase array data in a dropdown menu with Bootstrap-vue

Currently, I have an array of JSON data structured like this: loggers = [{ "allAvailableLevel": ['WARN', 'DEBUG', 'INFO'], "level": "WARN", "logger": "com.test1", "status": "success" }, { ...

What significance does it hold for Mocha's `before()` if the function passed requires parameters or not?

In one part of my code, I have a describe block with before(a) inside. The function a originally looks like this: function a() { return chai.request(app) ... .then(res => { res.blah.should.blah; return Promise.resolve(); }); ...

Having trouble navigating back to the homepage

Recently, I started following a tutorial on YouTube to create a basic frontend in React with Bootstrap. However, I encountered a roadblock while trying to implement a specific functionality. The issue stemmed from the fact that react-router-dom v6 no lon ...

Ways to create interactive multiple dropdown menu using vue-multiselect

I'm not sure if it's possible to achieve what I want with Vue for a specific component by changing its data and automatically loading it. Below is my expectation (tried in jQuery) var data = {country:{type:'dropdown',values:[' ...

Angular 14 is experiencing issues with NgRx Store failing to properly recognize the payload

The issue lies in TypeScript not recognizing action.payload.index as a valid property. I am unsure how to resolve this problem and make the 'index' visible in my project. shopping-list.actions.ts import {Action} from "@ngrx/store"; im ...

Dealing with an Ajax request that returns a file or partial HTML in the event of an error - what is the best approach?

Imagine a scenario where we are engaged in a dialogue with certain settings. Upon clicking the "OK" button in the dialogue, the settings are transmitted to a controller function through an AJAX call. This call may either yield a downloadable file or an err ...

Encountered an unexpected token '{' error in Discord.js and Node.js integration

let user = message.mentions.users.first(); if (message.mentions.users.size < 1) return message.reply('Please mention someone to issue ARs.').catch(console.error); mcash[${user.id}, ${message.guild.id}].mc ...