Best practise to deal with a index route that needs to load data


#1

In my ember app I want to display some data within the index route, that needs to be fetched from the server. This works pretty well, if the user accesses the page via the root url ‘my-app.com/’.

However, if the page is accessed via a previous state for instance a nested url ‘my-app.com/resource1/resource2’ then the ‘setupController’ hook of the index route does not get called and the model never is loaded.

I was working around that by loading that data within the first sub route e.g. ‘my-app.com/resource1’, if it hasn’t been already loaded. This however seems to be a pretty ugly workaround. Is there any way I could make ember to always load the index route?


#2

I think perhaps what you’re wanting to do is use the application route to load the data as it is always entered. The index route is actually a sibling to your top level routes.

Suppose your router looks like this:

Router.map(function() {
  this.route('route-a');
  this.route('route-b');
});

So, what you’re implicitly getting here is this:

- Application Route
  - Index Route
  - Route-A Route
  - Route-B Route

If the user enters route-a, then the index route is bypassed entirely because it’s a sibling (in the same way that route-b would be bypassed too). The application route, however, is always entered before any of those other routes are entered.

Then if you needed the data in the actual index route from the application route, you could do:

// app/index/route.js
import Ember from 'ember';

export default Ember.Route.extend({
  model() {
    return this.modelFor('application');
  }
});

Hope that helps!


#3

Thank you. That is an interesting idea. However, it has one issue within my application. The index route requires authentication, whereas the application route does not. Currently if the index route is accessed without authentication, the user is redirected to the login in route and then back to the index route, where the model gets loaded again. That does not work when the data is loaded within the application route. However, I could load the data in both places and just do nothing in the application route if the user is not authenticated. Still not as nice as I would like it to be, but probably better than my current workaround.


#4

My Bad. The application route would always conflict with authentication, as it should be available unauthenticated. So I would need to find a way to trigger a reload of the model after authentication, as the application route is not reloaded after authentication is done. However, I haven’t been able to find something like that so far.


#5

Just out of curiosity, what is this model/data that needs to be loaded for all authenticated users? Is this something that maybe should be part of a service? Maybe with some more clarification, we can find a better solution.


#6

The application consists of two parts which are always shows when a user is logged. A sidebar for navigation and a main part for editing/viewing.

The data that needs to be loaded are all the resources that belong to the user. So, when the user is logged in and enters ‘/’ I load all the groups the user is part of. The user then is able to select a group in the sidebar, which takes him to all the threads within that group. Selecting a thread, displays all the message within that thread.

the routes work like this:

'/'                        => sidebar: all groups 
'/group1'                  => sidebar: selected group + threads   main: data about the selected group 
'/group1/thread1'          => sidebar: selected group, thread + messages   main: data about thread1 
'/group1/thread1/message1' => sidebar: selected group, thread + messages   main: data about message1

#7

You don’t need to load everything at once. A list of groups would be sufficient to start off. Look into named/nested outlets. See here for some examples in the docs.


#8

Thanks for your reply. I don’t think that is the issue here. I load all the groups when they are needed (usually at the main site, when the user has signed in). I load the threads, when the group is selected, to which the threads belong… etc… The issue is about that I need to display the sidebar all the time. And when a user enters via an previously visited url, the ‘/group’ route does not get loaded. If I move that to the application route, this interferes with authentication, as the application route is only loaded once, which might be prior to authentication and there currently is no way to refresh a route.