Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait at least 2 seconds if ajax completed before transition.next() with Vue.js

I need to display the spinner for at least 2 seconds if ajax has been completed before transitioning.

I have the following but isnt working

route: {
    data(transition) {

        this.getDelayedData();
        transition.next();
       }
    },

methods:{   
   getSliders(){
            this.$http.get('/api/sliders/getsliders')
                   .then(sliders =>{this.sliders = sliders.data

              });
        },
   getPosts(){
            this.$http.get('/api/posts/getposts')
                    .then(posts =>{this.posts = posts.data.data

                    });
        },
   getDelayedData(){
       function timer() {
           var dfd = $.Deferred();
           setTimeout(function()
                    {
                    console.log("done");
                    }, 2000,dfd.resolve);
                    return dfd.promise();
                    }
           $.when( this.getPosts(), this.getSliders(),timer() )
                .done();
       }
    }

I tried to implement the code reading this post But the $.when function isnt waiting until the setTimeout function is finished executing.

like image 399
FerchoCarcho Avatar asked Oct 26 '16 00:10

FerchoCarcho


1 Answers

I believe the problem is caused because your methods - getSliders() and getPosts() are not returning any Promises. So your deferred timer has no way of knowing what is going on in these get methods.

Your this.$http.get(..) from Vue-resource returns a promise. You can return it as follows:

getSliders(){
    // Fetch sliders and "return" the promise object
    return this.$http.get('/api/sliders/getsliders')
        .then(sliders =>{
            // The data on vue is already being set here. So it will not wait for timeout.
            this.sliders = sliders.data
            // Instead you may try to set it on "this.sliders_temp" and then change later to "this.sliders"
        });
}, // and so on...

That follows the example given here: http://www.erichynds.com/blog/using-deferreds-in-jquery, which is linked in the other stackoverflow answer that you referred to in the question. They return $.get(..) in their functions.

But as indicated in my code sample above, even if you return this.$http.get(...), it will still not work for you, because you are already setting this.sliders inside your success handler for $http. So your Vue template will update the UI immediately. You need to think through a better strategy for your app.

like image 120
Mani Avatar answered Jan 25 '23 09:01

Mani