When routes are loading or there's an error, we have the ability to let the user know what's happening. This recipe will go over the basics on how to do this.
students
route:$ ember g route students
The ember generate
command will create all the necessary files for the students
route.
students.js
file in the app/routes
folder. Add a new model to return:// app/routes/students.js import Ember from 'ember'; export default Ember.Route.extend({ model(){ return new Ember.RSVP.Promise(function (resolve, reject) { Ember.run.later((function() { resolve( [1,2,3,4,5,6,7,8,9]); }), 2000); }); } });
In our route file, we are returning an Ember RSVP
promise. This promise resolves to a simple array that will be returned. Ember.run.later
is a built-in Ember method that is a part of the Ember run loop. It acts like the JavaScript's setTimeout()
. In this case, we are setting the timeout for 2,000 milliseconds so that we can simulate what might occur if the model was slow to load. After two seconds pass, the resolve will return with the array.
app/templates
folder:// app/templates/students-loading.hbs <h1> Loading! Please wait! </h1>
This substate will be loaded while the students route is loading. A loading substate is created by adding a template with the name of the route and a dash loading at the end. For example, for the students route in our example, we called the students-loading.hbs
substate. The application loading the substate would be application-loading.hbs
.
beforeModel
, model
, and afterModel
hooks don't resolve immediately, the loading event will be fired. Add a new loading action that displays an alert box while the model loads and transitions to the application route:// app/routes/students.js … }, actions: { loading(transition, originRoute) { alert('Sorry this page is taking so long to load!'); this.transitionTo('application'); } } …
The alert box will fire while the route is loading.
http://localhost:4200/students
and you'll see the alert box while the model is loading.Error substates occur whenever an error is encountered. It's very similar to the loading substate.
teachers
route:$ ember g route teachers
This will create all the necessary files for the teachers
route.
teachers.js
file in the app/routes
folder. Add a new Ember.RSVP.Promise
with a reject:// app/routes/teachers.js import Ember from 'ember'; export default Ember.Route.extend({ model(){ return new Ember.RSVP.Promise(function (resolve, reject) { reject('error'); }); }
In this example, we return a new Ember.RSVP.Promise
that will reject. This will cause an error to occur.
teachers-error.hbs
file in the app/templates
folder. This will be displayed when an error occurs in the teachers
route:// app/templates/teachers-error.hbs <h1>Error Loading!</h1>
Error substates, like loading substates, must be named after the route with a dash loading at the end. The template will be displayed during an error and doesn't need any other logic to occur.
// app/routes/teachers.js … }, actions: { error(error, transition) { alert('Sorry this page is taking so long to load!'); this.transitionTo('application'); } }
Using the error event is just another way to handle errors. We could certainly have created an error route to transition to.
The Ember route has built-in methods and events to handle errors and loading. When loading information, the model hook is waiting for the query to get completed. During this time, a template with the name dash loading at the end will be transitioned to immediately and synchronously. The URL will not be effected. After the query completes, the loading route will be exited and the original route will continue.
When dealing with errors, the error template will be loaded. Once again, the URL will not change to the error route. The error will be passed to the error state as it's model.