What is causing Vuejs to not recognize the status of my button?

I am currently developing a Vuejs website that allows users to jot down notes about meetings. Upon loading, the website fetches the meeting notes from the server and displays them. When a user adds new notes and clicks the "Save" button, the text is saved to the server. Once the notes are successfully saved, the Save button is disabled and a message saying "Saved" is displayed. When the user begins typing again, the button is re-enabled and displays "Save." This functionality may seem basic, but I am encountering some challenges with it.

Below are the HTML elements for the textarea and Save button:

<textarea v-model="selectedMeeting.content" ref="meetingContent"></textarea>
<button v-on:click="saveMeeting" v-bind:disabled="meetingSaved">
    {{ saveMeetingButton.saveText }}
</button>

Upon initializing my Vue app, I set up the data:

data: {
    selectedMeeting: {},
    meetings: [],
    meetingSaved: true,
    saveMeetingButton: {saveText: 'Save Meeting', savedText: 'Saved', disabled: true},
},

During the creation phase, the meeting notes are fetched from the server:

created() {
    axios.get('/ajax/meetings')
        .then(response => {
            this.meetings = response.data;
            this.selectedMeeting = this.meetings[0];
            this.meetingSaved = true;
        });
},

I have a method to save the notes:

methods: {
    saveMeeting: function () {
        axios.post('/ajax/meetings/' + this.selectedMeeting.id, this.selectedMeeting)
            .then(function (response) {
                this.selectedMeeting = response.data;
                console.log('Now setting meetingSaved to true');
                this.meetingSaved = true;
                console.log('Done setting meetingSaved to true');
            });
    },
},

I also have a watcher that triggers whenever there is a change in the text, saving the text immediately (even with every letter typed, which I will refine later). Here is the code snippet:

watch: {
    'selectedMeeting.content': function () {
        this.meetingSaved = false;
        console.log('Changed meeting ', new Date());
        this.saveMeeting();
    }
},

Upon typing a letter, the log shows:

Changed meeting  Tue Dec 04 2018 19:14:43 GMT+0100
Now setting meetingSaved to true
Done setting meetingSaved to true

Although the logs are displayed as expected, the button remains enabled. Removing the watcher causes the button to be disabled at all times. Despite the watcher correctly setting this.meetingSaved to false, and subsequently setting it to true with this.saveMeeting(), the watcher does not seem to disable the button as intended.

Could someone point out what I am doing incorrectly in this scenario?

Edit

For a complete view of the entire page, you can access it here: https://pastebin.com/x4VZvbr5

Answer №1

Your current setup could benefit from a few adjustments.

Firstly, it's important to note that the data attribute should be a function that returns an object:

data() {
    return {
        selectedMeeting: {
            content: null
        },
        meetings: [],
        meetingSaved: true,
        saveMeetingButton: { 
            saveText: 'Save Meeting',
            savedText: 'Saved',
            disabled: true
        },
    };
}

This structure allows Vue to properly bind the properties to each instance.

Additionally, the content property of selectedMeeting may not have existed during the initial render, causing Vue to miss updating it properly. Consider using Vue.set to address this issue.

Another suggestion is to utilize async/await for handling promises, as it can improve readability and maintainability of your code.

async created() {
    const response = await axios.get('/ajax/meetings');
    this.meetings = response.data;
    this.selectedMeeting = this.meetings[0];
    this.meetingSaved = true;
},

Similarly, consider implementing async/await in your methods for improved handling. You can also leverage Vue modifiers like once on click events to enhance user experience.

methods: {
    async saveMeeting () {
        const response = await axios.post('/ajax/meetings/' + this.selectedMeeting.id, this.selectedMeeting);
        this.selectedMeeting = response.data;
        console.log('Now setting meetingSaved to true');
        this.meetingSaved = true;
        console.log('Done setting meetingSaved to true');
    },
},

Overall, the code seems fine, but ensuring that the data function returns an object for reactive binding is crucial.

Looking ahead, consider implementing debounce on text input to control api call frequency and improve performance.

Answer №2

this.newMeeting = true;

this refers to the instance of the axios object. It is recommended to create a reference to the Vue object outside of your function call and then use it within. The same principle applies when using jQuery.ajax().

mounted() {
    var vm = this;
    axios.get('/ajax/newMeetings')
        .then(response => {
            vm.newMeetings = response.data;
            vm.selectedNewMeeting = vm.newMeetings[0];
            vm.newMeeting = 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 content based on information from an array using JavaScript

I am currently working on developing a user-friendly step-by-step form using AngularJS and UI-router to navigate through different sections. The data collected from each form is stored in a JavaScript array, and I am trying to dynamically show or hide a di ...

When using addClass("test"), it throws an error message: TypeError: undefined is not a function

Upon examination in the console, I discovered the following: $(".myCssClass")[0].parentNode <li><span class="myCssClass">some text</span></li> I am attempting to add a CSS class to the parent span tag within the <li> element ...

Selecting DigitalOcean city based on user location in Node.js

Currently, I am implementing Node.js in conjunction with my HTTP server. My goal is to have every user who connects to the server be linked to a real-time game server through WebSockets. Furthermore, I aim for users to automatically connect to the nearest ...

Detecting and removing any duplicate entries in an array, then continually updating and storing the modified array in localstorage using JavaScript

I'm facing an issue with the function I have for pushing data into an array and saving it in local storage. The problem is that the function adds the data to the array/local storage even if the same profileID already exists. I want a solution that che ...

Encode data in JSON format using Javascript and then decode it using PHP

In my coding journey, I decided to create an object using Javascript to pass it as an argument to a PHP script. var pattern = new Object(); pattern['@id'] = ''; pattern['@num'] = ''; pattern.cprop = new Object(); // ...

Transitioning classes in Vue elements

Is it achievable to create a smooth transition between two CSS classes with different background images? That's the challenge I'm currently facing. Here is the Vue code snippet I am working on: <div id="flip-list-demo" class="demo"> & ...

Combining two observables into one and returning it may cause Angular guards to malfunction

There are two important services in my Angular 11 project. One is the admin service, which checks if a user is an admin, and the other is a service responsible for fetching CVs to determine if a user has already created one. The main goal is to restrict ac ...

Concealing a division element if there is no content inside of it

As a newcomer to jQuery, I am experimenting with setting up a code that hides a div when the 'innerHTML' is null. However, my attempt using the code below is not working. Can anyone point out where I might be going wrong? if (($("#php-errors").h ...

Exploring the process of traversing a function for each ng-repeat element

Hey everyone, I'm currently facing an issue where I need to pass each date through a function in order to get the desired result. Let's take a closer look at the code snippet: <md-list> <md-divider ></md-divider> ...

What is the best way to ensure that this jQuery window has a minimum size?

Recently, I came across a helpful jQuery demo that demonstrated how to create a popup window on my website. For those interested, the demo link can be accessed here: http://jqueryui.com/dialog/#modal-message The design of the window I am aiming to replica ...

I am looking to include a popover within my modal using Bootstrap version 3.0.2

Hey there, I'm having an issue where the popover that should be inside the modal is actually appearing outside of it in the top left corner, not visible within the modal itself. Below is my index code: <button type="button" id="example" class="bt ...

Displaying Image Previews in Rails View Using JavaScript

I am working on a functionality where I have a text_field that contains the URL of an image. The goal is to load this URL into an img tag and update the preview image when the user changes the URL in the text field. Below is the relevant erb code for the ...

Switch up the key while iterating through a JSON object

Can you modify the key while iterating through objects using an external variable? Picture it like this: var data = [{ "id": 1, "name": "Simon", "age": 13 }, { "id": 2, "name": "Helga", "age": 18 }, { "id": 3, "name": "Tom ...

Issue with background image resizing when touched on mobile Chrome due to background-size property set to cover

My current challenge involves setting a background image for a mobile page using a new image specifically designed for mobile devices. The image is set with the property background-size: cover, and it works perfectly on all platforms except for mobile Chro ...

What is the best way to insert a new row into a table upon clicking a button with Javascript?

Hi everyone, I'm facing an issue with my code. Whenever I click on "Add Product", I want a new row with the same fields to be added. However, it's not working as expected when I run the code. Below is the HTML: <table class="table" id="conci ...

Exclusive Vue3 Props that cannot be used together

How can a component be created that accepts either json with jsonParserRules or jsonUrl with jsonParserRulesUrl, but not both? It would be ideal if the IDE could provide a warning when both props are specified. Example of an Attempt that does not Work < ...

Using MDBootstrap for reactjs, incorporating a modal into a table for enhanced functionality

As a newcomer to the world of React.js and Material Design Bootstrap, I am attempting to load a dataset onto a table using a mock JSON file. After some trial and error, I managed to achieve a certain level of success with this task. My goal is to include a ...

ES6 scoping confusion: unraveling the mystery

I stumbled upon these two syntax methods for exporting functions. Let's say we have files named actions.js and app.js. The first method looks like this: in actions.js export function addTodo() {} export function deleteTodo() {} and in app.js I have ...

Removing values in javascript for checkboxes that are not selected

Here is the JavaScript Code : var clinicalStat; var id; var val; var clinicalVals; $(":checkbox").click(function() { //alert(" you checked"); if ($(this).is(':checked')) { var checked1 = $(this).val(); //Inital value of check ...

Issues with date clicking on FullCalendar in Angular

I'm currently using version 4.4.0 of the FullCalendar plugin, but I am facing an issue where the dayClick event is not being triggered in my code. Below is a snippet of my code: calendar.component.html <full-calendar defaultView="dayGridMonth ...