6

There is a situation that I have to get extra data after my first ajax (in mounted function) in vuejs, I have put the second ajax in if condition and inside success function of the first ajax!

It is working and I see data in Vue Devtools in chrome, but data is not rendered in 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 url
                        if (getUrlParameterByName('conversation_id')) {
                             // Second Ajax Is Called Here inside First Ajax
                             return vm.getConversationMessages (getUrlParameterByName('conversation_id')); // this ajax call is getting data but not showing in view  
                        }
                    }

            },
       
           getConversationMessages : function(conv_id){
              // Second Ajax Call to get Conversation messages
              // and showing them , works onClick
               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 get a specific conversation messages is responding to onclick event and showing messages, but when this function is used inside the First Ajax success response (getParticipants()), its getting data correctly nd I can see in DevTools VueJs Extension that messages are set but view does not show messages, I have tried vm.$set() but no chance.

Update:

The second Ajax is working with no errors and messages data property get filled (I checked Vue DevTools), The only problem is that view does not show the messages!! but when I do it manually by clicking on a conversation, second ajax is executed again and I can see messages!, I also tried vm.$forceUpdate() after second ajax with no chance.

Update2 html part(the bug is here!!)

<a vbind:id="conv.id" v-on:click="getMessages(conv.id)" onclick="$('#user-messages').addClass('active')">
Community
  • 1
  • 1
Ahmad Mobaraki
  • 7,426
  • 5
  • 48
  • 69

4 Answers4

4

the DOM is updated with messages with when you do the ajax request with only getConversationMessages and not placing getConversationMessages in the success callback of the ajax request of getParticipants is the fact that an error is encountered at this line

this.participants = response.data.participants;

you are using a normal function in the success callback of the ajax request that's the reason this does not point to the vue instance adnd this.participants gives you an undefined error. So use vm insteaad to point to the vue instance as you did 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;
            });

        }

})
Vamsi Krishna
  • 30,568
  • 8
  • 70
  • 78
  • Tried `vm.participants` same results, as I mentioned, there is no error, the second ajax is working and I can see ajax result `messages` in console and in Vue Devtools, i.e : `$vm.messages` is filled with messages, the only problem is that the view is not rendered and I can not see messages in page – Ahmad Mobaraki Nov 22 '17 at 09:46
  • @AhmadMobaraki can you refactor the code as in my updated answer – Vamsi Krishna Nov 22 '17 at 10:12
  • Thank you, I will try. (I'll let you know in 2 or 3 hours!!) but i need my functions to be `success` function inside. because they should response to `onclick` event independently – Ahmad Mobaraki Nov 22 '17 at 10:49
  • I refactored my code as you suggested, but same result :( – Ahmad Mobaraki Nov 22 '17 at 15:38
  • @AhmadMobaraki Please update your question with the corrected code. – Roy J Nov 30 '17 at 21:10
  • @RoyJ What do you mean? my code is working, Vmsi Krishna's code is working too. I mean the second Ajax is working and `messages` data property get filled (I checked Vue DevTools), The only problem is that view does not show the messages!! but when I do it manually by clicking on a conversation, second ajax is executed again and I can see messages! :(, I also tried : `vm.$forceUpdate();` after second ajax with no chance – Ahmad Mobaraki Dec 01 '17 at 10:16
  • @AhmadMobaraki `this.participants = response.data.participants;` is not going to work because `this` is not `vm`. – Roy J Dec 01 '17 at 11:23
  • @RoyJ Sorry, yes I know that, in my real code all instances are `vm` not `this`, I will correct the question. – Ahmad Mobaraki Dec 01 '17 at 11:26
  • @RoyJ and Vamsi Krishna Thank you very much, the problem was in html! I updated the question again – Ahmad Mobaraki Dec 02 '17 at 12:22
2

Call second http request after first is completed using http callback or you can use Promise too.

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

   // first call
}).then(function(response){

// Second call
})
gaurav bankoti
  • 224
  • 1
  • 8
2

new Vue({
  el: '#messages',
  data: {
    participants: [],
    active_conversation: '',
    messages: []
  },
  methods: {
    async getParticipants (id) {
      var response = await this.$http.post('message/get-participants')
      this.participants = response.data.participants
      if (id) this.getConversationMessages(id)
    },
    async getConversationMessages (id) {
      var response = this.$http.post('message/get-messages/' + id)
      if (response.data.status === 'success') {
        console.log(response.data.messages)
        this.messages = response.data.messages;
      }
    }
  },
  created () {
    this.getParticipants(getUrlParameterByName('conversation_id'))
  }
})
-1

The problem for me was in html, I added a custom onclick event to the div element previously and this event was conflicting with Vuejs events.

Ahmad Mobaraki
  • 7,426
  • 5
  • 48
  • 69