FerchoCarcho FerchoCarcho - 1 month ago 15
Javascript Question

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.

Answer

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.

Comments