Ember 2.x

Ember 2.x Exercise 5 Solution, Part 1

Topics:

This course has been updated! We now recommend you take the Ember Octane Fundamentals course.

Check out a free preview of the full Ember 2.x course:
The "Exercise 5 Solution, Part 1" Lesson is part of the full, Ember 2.x course featured in this preview video. Here's what you'd learn in this lesson:

Mike walks through the solution to Exercise 5. He also spends a few minutes customizing the substate markup and answering some audience questions.

Get Unlimited Access Now

Transcript from the "Exercise 5 Solution, Part 1" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Michael: So the first thing we need to do is when we look at the instructions here, let me bring this up real quick. So when we consider transitioning from orgs to org/emberjs which is the name of that route is called org, we have to consider what are we pivoting on in this hierarchy of routes?

[00:00:27] And in this case, it is going to be the application route. And so the place we're going to put our loading.hbs file is right in the templates folder. So I'm gonna start by doing that. So it's this and I'm just gonna create a new file called loading.hbs and we'll start with loading...and we'll transition in.

[00:00:57]
>> Michael: I'm actually gonna add a little weight on the route just so that we can see what's going on here.
>> Michael: All right, so I've added two seconds of extra weight to this API request and we can see that as we drill in. Let's refresh here. So we get this loading state here.

[00:01:55] Make sure that still works.
>> Michael: Something's still odd [LAUGH] here.
>> Michael: It is, maybe I didn't save here let's see. Back to the list of orgs. I think I know what's happening here, I think that the actual weight we're looking for, so I may have gotten the pivot wrong here.

[00:02:28] Let me move this and see if it makes a difference. Move it into the org folder.
>> Michael: Man, this example just does not want to work with me. I'm gonna actually move on to the error substate here because that's a little bit more interesting. So the way to test this is to add something to your URL because we're building our API request URL, we're deriving it from the params that are passed through dynamic segments.

[00:03:13] So I'm gonna add something to make this invalid. There's my loading state there of course, [LAUGH] and you can see that GitHub is giving me a 404, right, and what's happening is we're throwing an error under the hood. This is bubbling all the way up to the application level error substate.

[00:03:37] We have no template there for that error substate. And so we're going to kind of just throw our hands up and make the screen blank. We can improve that first.
>> Michael: And I'm gonna take off my network link here. All right, so now we're in the error substate and we can put a debugger here to explore what's available to us, and the way you look at what's available in terms of data in your template is you look at context.

[00:04:27] [SOUND] And if you look at the code like where the break point is you can see that that's sort of what's pulled out. That's one of the things passed to handle bars as you're rendering. You have this context available here, right, so it's sort of the scope available to this template.

[00:04:49] And in this case, we have this thing called Model and we can get a status, status text. So I'm gonna actually render that here.
>> Speaker 2: Where is that template? Is that your application level?
>> Michael: Application level error.HBS
>> Michael: All right, so we've got error not found. We wanna handle this specifically though.

[00:05:20] We wanna handle this particular error in a particular way. So I'm gonna go back to this route here and I'm gonna add an action called error.
>> Michael: And I'll just put a debugger there for now. So we can make sure it's hit and see what's going on. Fantastic.

[00:05:46] And if we examine this argument, we can see that there is a status, and it's 404. So in this case,
>> Michael: I want to intermediateTransitionTo, and I'm just gonna call it org.notfound. It's a route that does not yet exist but that's cool, I'll create it later. And then otherwise I'm gonna return true which is, which means what?

[00:06:22] Bubble up.
>> Michael: So I'm gonna kick that to Ember CLI, ember g route org/notfound
>> Michael: And now this route should exist.
>> Michael: So you can see, we're seeing something different here. We're actually seeing this back to the list of orgs part of the template.
>> Speaker 2: So what is the intermediate transition 2 versus transition 202?

[00:06:57]
>> Michael: So, intermediate transition 2 is designed to take you to a state that is not mapped to URL. You can see that my URL here is actually still, it's still the bad URL.
>> Speaker 2: Got it.
>> Michael: And-
>> Speaker 2: Is that so that it doesn't replace where the route so that you can go back to it later if you need to?

[00:07:19]
>> Michael: In this case I'd wanna know exactly what happened, right? So in this case,
>> Michael: Imagine that we took you to a different URL, right? We went to slash org slash not found and then you hit the back button, what's going to happen?
>> Speaker 2: You go back to the not found thing and move it back up.

[00:07:41]
>> Michael: Yes. So you're gonna go and try to load it again and then kick out to not found. And then hit the back button and you'll be sort of caught in a loop. Here, I would just need to really change something and then I'll be in a better state.

[00:07:54] I don't know why my loading substate is totally cooperating now, but.
>> Speaker 2: Someone said they got it working with org-loading.hbs.
>> Michael: Let's try that.
>> Michael: So we'll rename this to org-loading.
>> Michael: Fantastic, I can see that it's working even though it's super fast.
>> Speaker 2: Why are you changing the name?

[00:08:32]
>> Michael: It's apparently a new convention in 2.2. [LAUGH]
>> Speaker 2: I got it working on-
>> Speaker 3: That's good though because you know what the problem is when you look at all the filenames across the top of your editor, you don't know where you are most of the time.
>> Speaker 2: Unless your editor tells you.

[00:08:51]
>> Michael: Sure.
>> Speaker 2: Right.
>> Michael: I'm gonna keep plugging away here. So, I want to customize this not found template in org.
>> Michael: Let's see. Here it is. Org not found.
>> Michael: Okay, so what we've done here is we've transitioned to a specific state for the notfound case. Now I'm gonna prove that this works by messing up that little token we started using yesterday.

[00:09:46] I'm gonna actually delete one character off of it which will throw an authentication error. It's a different kind of error. And that should bubble us up to unauthorized. So here we're showing that we can catch the not found error, sorta within the context of looking up an org, right, that is the kind of error that's very useful to surface to the user, because they can just fix their URL, or something.

[00:10:11] Maybe the GitHub org has been renamed. Could be. And then this kind of error, you kind of have to catch it with some over-arching thing.
>> Michael: And in terms of spinkit, I'll just show you how typically do this. You could bring in via bower, but this is so small that I just would drop it here, drop in the css, drop this into your loading, and can throttle my network again.

[00:10:58]
>> Michael: And you see we get a little fancy loading thing.
>> [INAUDIBLE]
>> Michael: Yeah, there is an add on for that.
>> Michael: So, this is my, let me make sure I cover all the bases here, yep, so this is the completed Exercise #5. I will commit this push it up, questions?

[00:11:23]
>> Speaker 4: Question, hey, man where would you put the AR.HPS that handles a wrong URL?
>> Michael: What kind of wrong URL?
>> Speaker 4: So the example is like org/badname.
>> Michael: So I think we already have something that will handle that. I think we've already done that. So if we do something like this.

[00:11:43]
>> Speaker 4: He said this one only works for org/badname. So maybe he's talking about more of like a global one?
>> Michael: Yeah, so we have some global one that we added as part of when we were talking about different kinds of segments, like dynamic segments versus star segments. If we look at our router, we've got this notfound catch-all here.

[00:12:09] So in this case we're handling all routes that don't match something specific in a particular way. This is different than getting a 404 from an API because we're talking about client-side routes versus I have looked up an entity and I cannot find this thing. So I think we actually handle both of those cases.

[00:12:33] The only thing that is making this a little confusing is, no, this should actually work. Is there a specific URL that he was talking about?
>> Speaker 3: If you look at chat [INAUDIBLE].
>> Michael: Only works for org/badname. So it'll actually work for any descendent of that route as well but remember that the error handling we put in place is for pivots on that route.

[00:13:08] Right, that's where our specific error handling happens. If we're pivoting on something else, the action is not going to fire on that particular route and it'll just bubble up straight to application.
>> Speaker 2: But, children is bubble up and get caught. So, the 404 on the repo gets caught by the.

[00:13:27]
>> Michael: Yes, totally, but if we were dealing with the orgs list, which has nothing, the route org is not active in that case. We have no specific handling for a 404 there. And so, this is something that you might want to extend Ember.route to make your own base class if this is something you wanna handle consistently in a generic way.

[00:13:54] But in this case, we are limited to only the specific case, but that was kind of the idea giving you guys guidance as to how you can catch something particular because the general stuff is easy to just do an application.