12

I'm trying to simulate a publication doing a bunch of work and taking a long time to return a cursor.

My publish method has a forced sleep (using a future), but the app always displays only

Loading...

Here's the publication:

Meteor.publish('people', function() {
  Future = Npm.require('fibers/future');
  var future = new Future();

  //simulate long pause
  setTimeout(function() {
    // UPDATE: coding error here. This line needs to be
    //   future.return(People.find());
    // See the accepted answer for an alternative, too:
    //   Meteor._sleepForMs(2000);
    return People.find();
  }, 2000);

  //wait for future.return
  return future.wait();
});

And the router:

Router.configure({
  layoutTemplate: 'layout',
  loadingTemplate: 'loading'
});

Router.map(function() {
  return this.route('home', {
    path: '/',
    waitOn: function() {
      return [Meteor.subscribe('people')];
    },
    data: function() {
      return {
        'people': People.find()
      };
    }
  });
});

Router.onBeforeAction('loading');

Full source code: https://gitlab.com/meonkeys/meteor-simulate-slow-publication

Adam Monsen
  • 9,054
  • 6
  • 53
  • 82

1 Answers1

33

The easiest way to do this is to use the undocumented Meteor._sleepForMs function like so:

Meteor.publish('people', function() {
  Meteor._sleepForMs(2000);
  return People.find();
});
David Weldon
  • 63,632
  • 11
  • 148
  • 146
  • Handy, thanks! I updated my question to show the coding error I made, too. – Adam Monsen Nov 08 '14 at 16:26
  • 6
    Hint: don't try to look to `Meteor._sleepForMs` at the client, it's a server-only method. – Tomas Romero Nov 08 '14 at 16:28
  • 1
    Question: This worked for me, thanks. But only once. I guess after the first load the publication is cached on the client. Is there a way to simulate a slower connection on every refresh? (Or at least to test it again?) – Arrowcatch Feb 24 '16 at 16:57
  • Yeah that's the expected behavior. Once the docs are subscribed to, you'll hit the client cache for them. In order to see the delay again you'd need to stop the subscription and start it again (or refresh the page, etc.). – David Weldon Feb 24 '16 at 19:41
  • Thats what I was thinking. But even on refresh the collection is almost instantly there. (Note: I have autopublish removed). You get the delay again, when you refresh? – Arrowcatch Feb 25 '16 at 06:03
  • 1
    Yes. A refresh of the page will kill all active subscriptions on the client. I'd recommend adding a console.log to see if the publisher is getting called. If you still can't figure it out, post a new question with the associated code. – David Weldon Feb 25 '16 at 06:12