Search code examples
javascriptmeteortimeoutpreload

How would I go about setting a minimum timeout function on a loading template


I want to have a loading template, with a minimum load time no matter if the data is ready. So basically run loading template for 1 second, even if the template and subscriptions are loaded?

My Router code below.

Router.configure({
  layoutTemplate: 'layout',
  loadingTemplate: 'loading',
  waitOn: function() { return Meteor.subscribe('contacts'); }
});

Router.map(function() {
  this.route('acorn', {path: '/'});
});

Router.onBeforeAction('loading');

Solution

  • You could accomplish this by wrapping the call to Meteor.subscribe and writing passthroughs for the ready and stop methods of the subscription instance. Your version of ready would only return true after a second has passed and the wrapped subscription is ready.

    Your waitOn method might look like:

    waitOn: function() {
        var sub = Meteor.subscribe("contacts");
        var dep = new Tracker.Dependency();
        var isSubReady = false;
        var hasWaitTimePassed = false;
    
        Meteor.setTimeout(function() {
            hasWaitTimePassed = true;
            dep.changed();
        }, 1000);
    
        Tracker.autorun(function() {
            isSubReady = sub.ready();
            dep.changed();
        });
    
        return {
            ready: function() {
                dep.depend();
                return hasWaitTimePassed && isSubReady;
            },
            stop: function() {
                sub.stop();
            }
        };
    }
    

    Of course, if you want to use this in many places, you'd want to wrap all the logic up into a reusable function so you could do something like:

    waitOn: function() {
        return subscribeWithDelay("contacts", 1000);
    }