Router pausing page load on slow API calls


#1

Using Ember RC3, I have routes kind of like:

App.Router.map(function(){
  this.resource("person", function(){
     this.route("jobs");
  });
});

If person’s model makes an Ajax request that takes a few seconds to respond, when I go to /person/jobs, does the router pause ALL ROUTES until that the promise resolves?


#2

Assuming you’re asking about router facelift (e.g. what will be released in RC6), then yes, it’ll pause. Future versions will likely make use of per-route loading states.


#3

@matchy Thanks for reply. I was actually asking about the current router, but it’s good to know how this will be handled in the future.

My issue was that I was using the model callback to make a slower API call. The router paused anytime I did a full page load, meaning an {{#if isLoaded}} call in my template (to add a spinner) wouldn’t get rendered until the model resolved.

The solution was to load the model (and handle the resolve) in setupController instead of the model callback. Makes sense now why that works, but was extremely hard to get to.


#4

@joefiorini the router pauses transitions when you return a promise from a model() hook. The problem is that Ember Data’s models and collections are promises by default, which most probably will be changed in a feature.


#5

I should have mentioned that in the application in question I’m not using ED but a custom base model. From what you said, does that mean I could drop promises from my models and still have it work? If that’s true, why would I want promises to pause the router in the first place?


#6

It really depends on how you want your UI to behave. If you return promises from model() user will have to wait till those promises are resolved (you should probably show some loading indicator then), but on the other hand if there is any problem with fetching those models, you can easily go to some kind of error page.

When you return non-promise objects from routes, your UI will render faster, but you will need to handle not loaded models and show errors differently. For example if you have a sidebar with a list and main view with detailed view and you’re not returning promises in routes, the UI will render immediately, but ideally you should show some kind of loading indicator for both list and post until they’re loaded. And then when loading fails you will have to either show it in the existing UI or redirect to some kind of error page.


#7

My issue is that there are two different behaviors depending on how I enter the route. If I transition into it then yeah, showing a loading indicator is fine. However, if I’m loading the route due to a full page load, then slower API requests cause the route to pause and not only does the loading indicator never get displayed, but the user is stuck with a blank page until the promise resolves.

Having lodged that complaint, I think @matchy’s facelift has fixed this problem by providing the beforeModel hook that on returning a promise will display a loading controller/template until the promise resolves. Really good stuff! http://jsbin.com/esusiy/1