18

I have an Ember application whose model comes from an Ajax call. The first call works great, I have the model hook of the Ember.Route return a promise to the Ajax call that retrieves the data to be displayed.

But this data changes frequently in the backend, and I want to have the webapp poll the server periodically, say, every 5 seconds, and update or, even better, swap the model data entirely with the newly retrieved one.

What is the appropriate way of doing that with Ember.js? I’m new to Ember so I’m a bit lost with this.

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
Edy Bourne
  • 5,679
  • 13
  • 53
  • 101

2 Answers2

33

I think this is a good use case for Ember.run.later, which limits the frequency of function calls.

You could just add a refresh to your model, similar to this:

App.Model = DS.Model.extend({
   poll: function() {
      var _this = this;
      Ember.run.later( function() {
         _this.reload(); 
         _this.poll();
      }, 500);
   }.observes('didLoad'),
});
Joe Czucha
  • 4,123
  • 2
  • 20
  • 28
chopper
  • 6,649
  • 7
  • 36
  • 53
  • Thanksfor the reply. In my case I'm trying to see what is the correct way of triggering those ajax calls and updating the model periodically using ember. This is something I'd accomplish with a setInterval if I were not using an MVC framework such as Ember. – Edy Bourne Feb 11 '14 at 18:49
  • 1
    Ohhh I see what you mean.. that's awesome!! thanks, I wish I could mark your answer as the correct one as well, or upvote more times :) – Edy Bourne Feb 12 '14 at 16:48
  • 5
    I think using `Ember.run.later` would be more appropriate here. The call to throttle is not going to throttle anything. (For throttle to be effective, you must use a function reference, not an anonymous function.) – Luke Melia Feb 13 '14 at 03:40
  • That's a good point, @LukeMelia - thanks. I made the appropriate changes. – chopper Feb 13 '14 at 17:03
  • wouldn't this run into _Maximum call stack size exceeded_ after some time? – aandis Feb 02 '19 at 16:26
  • @aandis it won't. The lamda function gets scheduled in the run loop and won't be executed for another another 500ms. You'd definitely have that issue if you didn't wrap `_this.poll()` in `Ember.run.later` (although that wouldn't achieve what the OP asked for) – chopper Feb 02 '19 at 20:54
2

If you are not using Ember data you can simply add a recursive setTimeout or setInterval in you controller and set the model property. Here is a simple example setting the model from a UI event.

If you are using ember-data I think the following threads have more accurate solutions:

Community
  • 1
  • 1
melc
  • 11,523
  • 3
  • 36
  • 41
  • 3
    Don't use setInterval. Memory leaks galore – jemiloii Jul 29 '14 at 09:57
  • 2
    another reason to avoid setInterval: it will cause asyncronous side-effects in your integration tests. See http://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905 – J. Barca Sep 30 '15 at 15:16