VueJS nested ajax requests successfully fetching data but failing to display content on the view

I am facing a situation where I need to retrieve additional data after the initial ajax call (in the mounted function) in Vue.js. I have placed the second ajax call within an if condition and inside the success function of the first ajax.

The data is successfully retrieved and visible in Vue Devtools in Chrome, but it is not being rendered in the view.

Pseudo Code:

var vm = new Vue({
         el: '#messages',
        data: {
            participants: [],
            active_conversation: '',
            messages: []
        },

        methods: {

            getParticipants: function () {
                   return this.$http.post('message/get-participants').then(
                    function (response) {
                      
                        vm.participants = response.data.participants;
                        // if there is a conversation_id param in the URL
                        if (getUrlParameterByName('conversation_id')) {
                             // Second Ajax Call Occurs Here nested inside First Ajax
                             return vm.getConversationMessages(getUrlParameterByName('conversation_id')); 
                        }
                    }

            },
       
           getConversationMessages : function(conv_id){
              // Second Ajax Call to retrieve Conversation messages
              // and display them, works with onClick event
               return this.$http.post('message/get-messages/' + conv_id).then(
                    function (response) {
                        if (response.data.status == 'success') {
                            console.log(response.data.messages)
                            vm.messages = response.data.messages;
                            vm.$forceUpdate();
           }
        },


      mounted: function () {
            this.getParticipants()
        }

})

The second Ajax call to fetch specific conversation messages works when triggered by an onclick event and displays the messages. However, when this function is called within the success callback of the first Ajax (getParticipants()), the data is fetched correctly as shown in DevTools, but the messages are not displayed on the screen. I have attempted to use vm.$set() without success.

Update:

The second Ajax call is functioning properly with no errors, and the messages data property is populated (confirmed through Vue DevTools). The only issue is that the messages are not displayed on the view! When manually clicking on a conversation, the second Ajax call is triggered again, and the messages become visible. I also tried using vm.$forceUpdate() after the second ajax call, but it did not resolve the issue.

Update2 html part(the bug is here!!)

<a vbind:id="conv.id" v-on:click="getMessages(conv.id)" onclick="$('#user-messages').addClass('active')">

Answer №1

When making an ajax request to update the DOM using only getConversationMessages without placing it in the success callback of the ajax request for getParticipants, an error occurs at this particular line:

this.participants = response.data.participants;

The reason behind encountering an error is due to using a regular function in the success callback of the ajax request, causing this to not refer to the Vue instance and resulting in an undefined error for this.participants. To resolve this issue, use vm instead to point to the Vue instance, as demonstrated in the rest of the program:

vm.participants = response.data.participants;

Edit:

var vm = new Vue({
         el: '#messages',
        data: {
            participants: [],
            active_conversation: '',
            messages: []
        },

        methods: {

            getParticipants: function () {
                 return this.$http.post('message/get-participants');
            },

           getConversationMessages : function(conv_id){
               return this.$http.post('message/get-messages/' + conv_id);
           }
        },


      mounted: function () {
            this.getParticipants().then(function (response){

                vm.participants = response.data.participants;

                if (getUrlParameterByName('conversation_id')) {
                    return vm.getConversationMessages (getUrlParameterByName('conversation_id')); // this ajax call is getting data but not showing in view  
                }
            }).then(function(response){
                if (response.data.status == 'success') {
                console.log(response.data.messages)
                   vm.messages = response.data.messages;
            });

        }

})

Answer №2

To make a second http request only after the first one is completed, you can either use an http callback or make use of Promises.

return this.$http.post(function(response){

   // code for the first call
}).then(function(response){

// code for the second call
})

Answer №3

const ChatApp = new Vue({
  el: '#messages',
  data: {
    participants: [],
    active_conversation: '',
    messages: []
  },
  methods: {
    async fetchParticipants (id) {
      const response = await this.$http.get('api/messages/participants/' + id);
      this.participants = response.data;
      
      if (id) {
        this.fetchMessages(id);
      }
    },
    async fetchMessages (id) {
      const response = await this.$http.post('api/messages/get-messages/' + id);

      if (response.status === 'success') {
        console.log(response.messages);
        this.messages = response.messages;
      }
    }
  },
  created () {
    this.fetchParticipants(getUrlParameter('conversation_id'));
  }
})

Answer №4

My issue arose from my HTML code - I had included a custom onclick event in the div element which ended up conflicting with Vue.js events.

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

The OutlinedInput component from Material-UI seems to be struggling to display the startAdornment

Below is the code snippet. The start adornment is not displaying in the textfield, and there is no text appearing on the label. <InputLabel>Mobile Number</InputLabel> <OutlinedInput variant="outlined" ...

Ember.js alternative for Angular's filter for searching through ng-models

Looking for an easy way to implement a search filter similar to Angular? <input type="text" ng-model="resultFilter" placeholder="Search"> <ul> <li ng-repeat="result in results | filter:resultFilter">{{result.name}}</li> </u ...

Typescript gives you the ability to create a versatile writing interface that includes all

Think about this: interface Options { length?: number, width?: number } interface Action { performAction ({length, width}: Options): void } const myObject: Action = { performAction ({length, width}) { // do something without returning ...

The functionality of event bubbling appears to be ineffective while utilizing a bootstrap modal in an AngularJS application

I have a question regarding the use of Bootstrap modal. To begin with, I apologize for any issues in understanding my question due to my English skills. I have created a button as a directive to dynamically add, with reference to the following links. . ...

Incorporate an external object not native to the Angular framework within a factory

We're in the midst of a debate and I'm hoping you can help us reach an agreement. Imagine I have a basic factory set up like this: angular.module('myModule', []) .factory('Fact', function() { var Fact = function() { ...

Tips on scrolling down to find the text you're looking for

I attempted to scroll downwards in my application's window using the following JavaScript code: ((JavascriptExecutor) driver).executeScript("windows.scrollBy(0,500)"); Additionally, I tried to ensure a specific element is in view with this script: ...

Issues with ASP.NET arise when losing the selection in a dropdownlist that was populated using javascript

On my webpage, I have two ASP.NET dropdownlist controls. The first dropdownlist retrieves an array from the server and uses it to populate the second dropdownlist through javascript. However, when I select an option in the second dropdownlist and then perf ...

margin-top: automatic adjustment, with a minimum of 50 pixels

I am trying to add a minimum of 50px margin to the top of my footer tag using CSS, but I haven't been successful with the min() function. I'm not sure if I am overlooking something or if there is another correct approach to achieve this. * { ...

To retrieve data from an AJAX response, you will receive an array in the form of a string

After requesting a list of posts submitted by users from my server, the response I received was a string containing an array of stdClass objects. If it had been an actual array, that would not have been an issue. However, it arrives as a string in the foll ...

Is it possible to prevent users from clicking on a jQuery UI Datepicker?

Is it possible to disable the functionality of a jQuery UI Datepicker so that clicking on it does nothing but display the date? I attempted: $("#calendar").datepicker({ disabled: true, altField: '#note_date', maxDate: 0 }); Unfortu ...

Utilize the HTTP path to designate the currently active tab

Here is a sample code snippet for vertical tabs in React using the Material-UI library: import * as React from 'react'; import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import Typography from '@ ...

Can SVN hooks be incorporated into NPM in a way that is comparable to git hooks?

I want to incorporate an npm script that performs linting and testing before executing an svn commit. If there are any failures during the linting or tests, I want the commit process to halt, similar to a git commit hook. Does anyone have any recommendat ...

Where should I set a value to ensure all listeners are triggered?

In my AngularJS view, I have a dropdown that triggers a function when the color is changed: <select ng-change="shop.updateSizes()" ng-model="shop.color" ng-options="color.name for color in COLORS"></select> The updateSizes method in my contro ...

Switching hover behavior on dropdown menu for mobile and desktop devices

I have implemented a basic JavaScript function that dynamically changes HTML content based on the width of the browser window. When in mobile view, it removes the attribute data-hover, and when in desktop view, it adds the attribute back. The functionalit ...

What methods can I use to adjust link distance while using the 3d-force-graph tool?

Exploring the capabilities of the 3D Force Graph from this repository has been an interesting journey for me. I am currently seeking ways to adjust the bond strength between nodes. I am specifically looking to modify either the link width or length, but ...

"Performing an Ajax request that mimics the functionality of a

My backend engineer provided me with a curl command that works perfectly in the command line. Now, I am attempting to translate it into ReactJS using ajax, since I couldn't do it directly. curl -v -H "Origin: http://example.com" -H "Access-Control-R ...

What is the proper way to credit the glyphicons element in Twitter's bootstrap framework?

According to the section on icons in the Base CSS page of GitHub's Twitter bootstrap, Glyphicons Halflings were not originally available for free. However, thanks to an agreement between Bootstrap and the creators of Glyphicons, developers can now use ...

Saving JSON data as a file on server

Currently, I am running a localhost website on my Raspberry Pi using Apache and I am seeking advice on how to export a JSON string to a file on the Raspberry Pi itself. While I do know how to export a file, I am unsure of how to send it to the Raspberry Pi ...

Procedure for distributing proportions

Imagine having an object like this: const data = { bills: 10, rent: 40, food: 50, } The total is 100 (or 100%). If we update the bills to a value of 20, the other properties should adjust accordingly, for example: { bills: 20, re ...

When attempting to make an AJAX call using the console, an error was encountered stating that the function $.ajax is not available

Currently experimenting with an ajax call from my console to a local server, but encountering an error: VM4460:1 Uncaught TypeError: $.ajax is not a function(…) Here's the code snippet causing the issue: url = 'http://localhost:8080/testform ...