Managing modifications within an array of objects proves to be a challenge when utilizing Vue.$set

I'm facing an issue with my computed attribute 'alphabet', which contains a list of objects, each with attributes letter (a string) and guessed (a boolean). I've been attempting to bind the guessed attribute to a class using Vue.$set instead of an equality operator, as per the documentation's suggestion. However, even after trying this, I can't seem to make it work.

Setting the guessed attribute to true by default did work, indicating that the problem doesn't lie in my CSS configuration.

To confirm that the value of the guessed attribute is changing, I printed out the alphabet object in the console (and it did change). The issue seems to be that, for some reason, the value isn't being updated reactively in the HTML.

Here is how I've configured the list:

<ul>
    <li v-for="(letter, index) in alphabet"
        v-bind:key="letter.id"
        @click="makeGuess(index)"
        v-bind:class="{guessed: letter.guessed}">{{letter.letter}}
    </li>
</ul>

On the last line, I'm attempting to connect the guessed attribute with the class.

This is my alphabet attribute:

computed: {
    alphabet: function () {
        var objects = [];
        var letters = "abcdefghijklmnopqrstuvwxyz".split("");
        letters.forEach(function (element) {
            objects.push({
                letter: element,
                guessed: false
            })
        });
        return objects;
    }
}

And here is my makeGuess function:

methods: {
    makeGuess: function (index) {
        if (this.word.includes(this.alphabet[index].letter)) {
            this.$set(this.alphabet, index, {
                letter: this.alphabet[index].letter,
                guessed: true
            })
            console.log(this.alphabet)
        }
    }
}

The expected outcome is for the guessed class to be added reactively when letter.guessed is true, but it's not happening. What am I missing?

Answer №1

To make changes to the output of a computed property, you must adjust the inputs for that property so it can be recalculated with all the necessary information.

Vue does not automatically track changes in objects or arrays returned by computed properties under the assumption that these values remain immutable. This means only the initial data needs to be observed.

An easy fix is to move the alphabet array into the data section instead of using a computed property:

data: function () {
    var letters = "abcdefghijklmnopqrstuvwxyz".split("");

    var alphabet = letters.map(function (element) {
        return {
            letter: element,
            guessed: false
        }
    });

    return {
        alphabet: alphabet
    };
}

By doing this, all changes will trigger reactivity without the need for a computed property or $set.

If moving it to a computed property is not an option, such as when the letters come from a prop, then a more complex solution is required. In that case, you'll need a data structure to store guesses, like this:

data: function () {
    return {
        guessed: {}
    };
}

The computed property would then look like this:

computed: {
    alphabet: function () {
        var letters = "abcdefghijklmnopqrstuvwxyz".split("");
        var guessed = this.guessed;

        return letters.map(function (element) {
            return {
                letter: element,
                guessed: guessed[element]
            };
        });
    }
}

Lastly, you would use the makeGuess method like this:

methods: {
    makeGuess: function (index) {
        var letter = this.alphabet[index].letter;

        if (this.word.includes(letter)) {
            this.$set(this.guessed, letter, true);
        }
    }
}

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

Show a variety of months using a datepicker arranged neatly in rows and columns

I need to display 13 months using multidatespicker. I achieved this with the following code: $(document).ready(function(){ $('#my_calendar').multiDatesPicker({ numberOfMonths: [4, 4], dateFormat: 'dd-mm-yy&a ...

Angular 5 requires the Google Map API call to be made before initiating the http get request

I am experimenting with URL parameters to make a GET request and then use JSON output to drive a query in Google Maps. Currently, I have managed to make the embedded map function by sanitizing it and passing static data. However, when making the query call ...

Accessing a hyperlink in an alternative browser

Is there a way to transfer a link from one browser to another? For example, moving a link from Firefox to Chrome or from a Chrome Incognito window to a regular Chrome window. Let me provide more context. I have a webpage that refreshes every second and us ...

Is there a way to retrieve a list of functions using ScriptEngine in Java?

I am using Jsoup to extract the JavaScript portion of an HTML file and store it as a Java String object. Furthermore, I am looking to extract lists of functions and variables within the JavaScript functions using javax.script.ScriptEngine. The JavaScript ...

I am looking for ways to identify the specific code responsible for causing a JavaScript heap out of memory issue

When I attempt to execute yarn start, I encounter the following error message: Starting the development server... ts-loader: Using [email protected] and C:\DevTools\git\mymoto\tsconfig.json <--- Last few GCs ---> [9076:000 ...

What steps can I take to ensure that my bot disregards any actions taken by other bots?

I need assistance with configuring my bot to ignore certain actions by other bots and prevent logging them. Below is the snippet of my code: let messagechannel = oldMember.guild.channels.find(r => r.name === config.logsChannel); if (!messagecha ...

What role does the cleanData function play in jQuery?

While delving into the inner workings of jQuery, I came across the cleanData function multiple times. It is called by jQuery.remove() and other functions alike. What is the significance of invoking cleanData before removing a DOM element? Is jQuery's ...

Having trouble with React list.map not functioning properly while deleting items from local storage?

I'm currently developing a budget tracking application that allows users to input various incomes and expenses. To manage the state of this app, I am utilizing useReducer. Each income and expense is represented as an object, and upon submission by the ...

Exploring the power of hierarchical organization in node.js modules

One of my modules is called UserProvider and it has the following structure: var UserProvider = function(db) { ... } UserProvider.prototype.createUser = function(email, password, callback) { ... } UserProvider.prototype.findUserByEmail = function(email, c ...

Struggling to create a line break within an SVG using the <tspan> element?

I have a pair of text lines that are wrapped in <tspan> tags. <tspan dy="-11.7890625">welcome</tspan> <tspan dy="16.8" x="285.75">text</tspan> I am trying to add a line break between them, but the <br> tag is not worki ...

Begin the Desktop PWA in immersive full-screen or kiosk mode

I've been on the lookout for a solution, but nothing seems to do the trick. My goal is to launch a PWA from a Windows Desktop computer using Chrome in kiosk mode or at the very least, full-screen (without any menu bars). I would have expected this to ...

Is the "connectToStores" method becoming obsolete in React/Flux applications?

Currently, I am in the process of constructing a small chat application using React and Flux by following a tutorial. However, it appears that the tutorial is outdated as it references a method from Alt (utilized with Flux) that triggers the following erro ...

Reverting to the original order in jQuery DataTables after dropping a row

Recently, I've been attempting to utilize jQuery DataTables in conjunction with the Row Ordering plugin. At first, everything seemed to be functioning properly until a javascript error popped up indicating an unrecognized expression. After researching ...

When using Sequelize.or, only the first result is returned instead of returning all results

Currently, I am integrating SequelizeJS(MySql) with Passportjs for authentication. When I try the following code: User.find(db.Sequelize.or({ 'username': username }, { 'email': req.body.email }) ) .then((user) => {consol ...

JavaScript code to automatically pause/play HTML5 videos when scrolling

I'm working on creating a video gallery using HTML5 and JS. I've managed to set it up so that you can scroll horizontally between autoplaying muted HTML5 videos, and the videos play or pause when scrolled into or out of view. Everything is functi ...

The functionality of Events javascript seizes to work once new content is loaded into a div through Ajax

On my website, I have a table where clicking on the first checkbox automatically selects all others and triggers additional actions. The data is loaded directly onto the page using PHP when the site opens. View image here Above the table is a 'selec ...

I'm looking to publish my Vue project on GitHub Pages, what steps do I need to

After creating a stock Vue project using the command: vue create test I am following the deployment steps outlined on Vue's official website at this link. However, when I attempt to execute the command: bash deploy.sh The build process is suc ...

Is requesting transclusion in an Angular directive necessary?

An issue has cropped up below and I'm struggling to figure out the reason behind it. Any suggestions? html, <button ng-click="loadForm()">Load Directive Form</button> <div data-my-form></div> angular, app.directive(&apos ...

Guide on properly documenting custom function types in JSDoc or TypeScript to ensure accurate referencing for VSCode IntelliSense functionality

I am currently working on documenting custom function types within an object and would greatly appreciate any assistance: A Closer Look at the Issue Consider this basic object declaration with several function properties (addCoordinate, addCoordinateOne, ...

Integrating Facebook login with Cordova using the cordovaOauth plugin

Encountering issues while setting up FB login for my cordova mobile app. A tutorial followed: http://www.codeproject.com/Tips/1031475/How-to-Integrate-Facebook-Login-into-a-Cordova-App#_comments <script src="js/angular.js"></script> <scrip ...