In AngularJS 1.2.x routing has changed. It is now required that you explicitly import ngRoute in your applications! This lesson uses an older version of AngularJS that pre-dates this change.
<script src="angular.js"> <script src="angular-route.js">
Scroll down to view the full corrected code for this lesson.
We can intercept a route change error and direct the user to an appropriate page.
John Lindquist: I've kind of coded myself into a corner here to prove a very important point. You might be thinking to yourself, what happens if the data fails to load? I'm going to get rid of the second promise. Instead of resolving this, I'm going to reject it. Hit refresh and you'll see that if we have it set up this way, absolutely nothing will happen if the data fails to load and there's nothing you can do on your controller to grab it.
Controlling will never be instantiated. Your view will never load. You're pretty much out of luck. What you should do when your site first loads up is always have a controller that can handle that sort of failure. Instead of using your app controller to be the controller that gets tied to the view, we're going to rename this to "view controller." We're going to use the view controller whenever this is created.
Now, instead of having the app controller do all that work, you grab this one. As far as setting up the scope, we're going to have our app controller handle the more basic stuff, like what happens when route changes fail. The app controller has the root scope because this guy is going to listen for any of the events that come up to the root scope. We'll get more into advanced root scope later on. It's good to be at least aware of what's going on.
Let's say root scope on, and the event we're going to listen for is route change error. Then we'll have a callback in here to say "failed to change routes." Basically what we can do now is refresh and it says "failed to change routes." We successfully handled this error. This would be something like if we made an http request and it failed to load. You can just reject it and send it back. We can do something now that this has failed.
Now that we can do that, there are some other parameters you should know about. The first one will give you more info about the event. The second one is the previous route, the route that existed before you got to this one. I think it's current then previous. I'll double check. The last one is the rejection.
If you want to pass a custom rejection message, you can just pass it through here. Say your network is down and then we could log out or handle that however you wanted. We'll just say "rejection." This is just going to pass straight through here, fire it into here. You can handle it here.
Your network is down. Let's just shorten this for brevity's sake. Let's double check the current and previous. We'll log out of current. This is right because that's the current path we're trying to get to. Then the previous should be undefined because we didn't have a path before we got here. We're good there.
Then, just look at the event real quick before we get into other events. You can see we have "route change error" as the name of the event. The other things that it passes along, like the scope, with any of the events they could fire it off.
Again, just to recap what we did there, we refactored what we use as the app controller into a view controller; something that will get used whenever that view is loaded. Then we created a new app controller and reassigned it to the root element of our app.
We're going to use that to handle these kinds of global things that can fail or at least global within our module, such as a route change error. Within a route change error we can handle it using properties from the event, the current route or the previous route.
We can get more into advanced routing to look at the differences between current and previous or just send some sort of rejection object you can handle and throw any sort of error you want to the user.