N Things You Didn’t Know About the Router - Deborah Kurata

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
thank you can you hear me okay yeah there it goes all right so we're gonna talk about and things that you don't know about the router why n because I'm not sure how much you all know about the router so my hope is that you will leave this session with finding out at least one thing that you didn't know before or that you might not have thought about a particular way before I have one slide on how the router works just to ensure we're all on the same page with regard to the terminology and then we're gonna jump right into our and things so how does routing work and why do I have a weird thing in the middle of my screen that's not me is that just a thing on the screen okay anyway all right hopefully you'll be able to see around that so how does routing work well frequently we have a tool bar or some kind of something around our application that allows the user to navigate around behind that we might have something like this a router link that identifies what path that we want the user to take when they click on that link when the user does click on that it changes our URL so that it has that path on it the router recognizes hey we've got a new something on the path and it goes and looks for a route configuration so what angular does is it takes any routes configured in your application and puts them in one combined list so it has one merged list of all of our routes and it starts at the top and finds the first match so in this case it'll find the path movies know to load the component movie list component so it loads that component find the Associated template loads and prepares that then it starts to look for an appropriate router outlet so it finds the router outlet and that's where it displays the components template so that's in one slide how the router works hopefully that was helpful for any more newer developer angular people here in the audience with that we're going to launch right into our first of n things - menu or not - menu this is one of the questions that get often how do we deal with the fact that some of our pages we want to route with a menu on the top and some of them like our login page we might not want to have our menu on the top so how do we deal with that well looking at our app component HTML we can see that we have our nav bar with our router links and under it is our router outlet so anything we route to that router L it's going to have our menu on top that's because we're telling it to do it that way so how do we deal with not having it do that what this will do is it will appear like this well we've got our menu across the top and then our app router outlet is the area underneath underneath it so how do we make it not do that well one option is we could have some kind of global flag with an NG F and then every component wouldn't need to turn that on or off now as soon as we hear the word global we should be thinking mmm right we don't want to we don't want to do that so what would be another way to handle this well we can change our app component from all of this to just that so that our main app component is only the router outlet then our whole browser area is our app router outlet and we can log things that we don't want the menu into that route or outlets so we can put our log in there all right so but we still need our menu somewhere so what we can do is we can create a another component I called mine shell component and this is where we then have our router link and now we have a second nested router outlet so now we've defined a hierarchy of router outlets for our application now we can simplify this code even further by taking out our menu stuff putting it into our own menu component and then we end up with our shell component looking something like that with just our nested router outlet and a reference to our menu component so then we have our a Prada Outlet which was the whole display underneath in our browser client area we can route to that then our shell component so our how our menu shows up then under nested inside a it has its own shell router outlet and then we can route into there our movie list or our movie detail or movie edit anything that we would want to appear under the menu bar nested router outlets okay well so what does that look like in code how do you actually make that work in code in our route configuration at the outermost level anything at that level is going to go to our outermost level of our router or router outlets so in this case it will be our route app router outlet anything that we want to appear in the shell components router outlet we define as children under the shell components so that way it knows which level of the hierarchy to put them in okay all right so that's to menu or not to menu our next item is preventing partial page display now when we as developers run our application we frequently get really good performance right we're frequently running our servers on the same machine or even have test servers we're running and we might not notice that when the users actually get the application it shows up like this so here's our detailed page with the static text a few moments later finally the data shows up okay so our users might not want that kind of behavior what are our options for dealing with that well one of the options that some people like to use is a resolver I kept calling this a reducer I've been doing a lot of energy are excellently calling it a reducer that's not a reducer it's a resolver so if I accidentally say reducer that's know what I mean so a resolver service and our resolver service implements resolve you tell at the data you want to resolve we're doing movie details so I want a movie I'm passing in my movie service so what is a resolver why am i passing in the service what am I really doing with this well a resolver is part of routing and what it does is it allows us to execute an asynchronous operation and have the routing wait for the completion of that asynchronous operation so what we're going to be doing here is our HTTP calls which of course are asynchronous operations so I'm passing in my movie service because that's my data access service that does my HTTP requests I go to my route to get my ID because this is a detail page so I have to know which movie I'm displaying the detail for and then I call this dumb movie service get movie and notice that I do not have a subscribe on there the resolver will automatically subscribe for me and then it will wait until the data is returned before it continues with the route because this is a service we need to add it to the providers array in our configuration we add the resolve property to our configuration specify a name and the class name and that associates a resolver with a particular path in our component a configuration then in our actual component did you want that again you got it okay in our actual component then we no longer need to use our service because our resolver already got the data so in our ng on a net we can set our data property to this dot route dot snapshot data and pass it the name the name again was the name that we had specified in the routing module there so notice that we now are treating our data as from our components point of view like it's a synchronous operation so what does that mean that means that our template no longer need NEADS ng-if at the top to deal with the fact that we might not have gotten our data yet it doesn't need safe navigation operators and so on because we will have received retrieved the data before actually even navigating ok so that's how we prevent partial page display one of the ways to do it but if you kind of think this through the user still has to wait somewhere right so in our particular case we have our list page that the user is clicking on and what we're going to want to do to not the user know that we're waiting at this point is to display a spinner so how do we display a spinner well one easy way to do it is to use routing will use routing events so we can actually subscribe to router events now in this case I'm doing it from app component which means that none none of my other components need to know anything about this spinner it will just automatically appear anytime that there is a delay in moving through the route so check router event is a method that I wrote that does this so if the event is a navigation start it sets a local property to true if it's n cancel or error it sets that local property to false then in my app component HTML remember this is the one that only had our router outlet on it I use my ng F and then whatever visual this uses the old bootstrap but whatever visual that you want and this will automatically appear anytime there's a delay in routing so you'll get the spinner anytime that there's a weight none of the other components need to know to do that all right what's going on what if your routes don't work so you've put your routing in and it's not working correctly it's either not routing or it's not changing routes or something is going on how do you do bugs ease things well you can set it up and I know this might be hard to see cuz this is kind of little but you can turn on routing such that you can see a trace of all of the routing events so all the around events I mentioned navigation start and so on if you can kind of see up in the front I've got a resolve start and then I've got data there that's my data access service going logging it's data retrieval and you can see that that's happening before it actually completes the navigation so how do you turn this on in your app routing module you just add enable tracing true okay and that turns it on and then after you've resolved whatever issue you might have with your routing you can just set it back to false or delete that a little bit again alright guards at the ready one of the other things you might want to do with your routing is guard your routes so you might want some routes that the user can only access if they're logged in and if they're not logged in have it pop up a login dialog or a login page other routes you might want to prevent them from navigating away why would you ever want to prevent someone from navigating away well say we have an edit page such as the one shown here and the users just made a whole bunch of edits and then they click back on the movie list and we don't want them to lose their edit so we could put up a little message saying hey do you really want to lose your edits or if we're pretty confident they meant to save those edits we could autosave them or we could do you know whatever that we would want there but we can capture that action we build a guard service very similar to how we build our resolve our service we implement the name of the guard so in this case it's can deactivate we could also do can activate can load and so on here I'm using the generic parameter to pass in the component that's being deactivated the can deactivate can take in the component that's being deactivated now that's a really important point because since we're getting the component that's about to be deactivated we can actually reference it so we can ask the component hey do you have dirty data so that we don't say to the user hey do you really want to save your changes and the users like I didn't change anything so that way we can check that we can access its data anything that we want we return true from the method if we want the routing to just continue as normal we return false if we want to cancel all of the future routing events for that particular route activation okay because it's a service we register the guard and then again we add it to our configuration by specifying another property which is the name of the guard so can deactivate in our case and then give it the class name of the guard service that we write okay so that's how we do guards keep constant now this one a lot of people probably already know about because a lot of examples already show how to do this here this is intentionally meant to be difficult to read the point here is that this is difficult to read now because we have all of our route stuff actually kind of connected in to our ng module decorator and that makes it hard to read it makes it hard to read the decorator because there's so much other stuff in there so the idea is we're going to pull that stuff out of there and we're going to put it into a constant at the in our class file so there's the definition of the constant and you can see now that's much easier to read you've also can see that I've added a few more I added a second level of router outlet here so now I have two sets of children one that's going to route into the shell component and another further down that's going to route into the movie edit component that allows me to have a tabbed edit dialog as you might have noticed on the prior slides ok so then our ng module decorator looks much simpler we just define our constant there and that makes that easier to read and work with as well ok it's a feature now we've all been taught that we don't put all of our code in one code file we don't put all of our angular application in one angular module oh I went hiking in Moab right before I came and I've been sneezing ever since I feel like I'm about to sneeze anyway I'll try not to do it in the mic so it's a feature so what about feature module so here we have our constant and we really want to take our movie stuff out of there because it doesn't belong in there it should be in a feature module instead so what do I do cut paste not too difficult then I do router module for child and pass in my constant but it won't work and you're like what I know that works I do that every day what are you talking about absolutely that works I put that in my code in our particular example this will not work why won't it work well somewhere in our application as soon as we decide we want feature modules we have to pull that feature module in so somewhere we're going to have an import so we're going to import our movie module into our app module or in into RF routing module or however our our standards to find where this should be imported what that's telling angular to do is to merge our routes remember I said at the very beginning that angular takes all of our routes and makes one big list of route configurations and then goes through top to bottom so what this guy is going to do is it's going to merge our routes so we're going to have our movies routes first because we've specified it first there and then it's going to have our other route where is our movie list component going to route to now at this point which router outlets going to show up is it going to show up in it's on the outermost set of our configuration so our movie list route or movie list component our movie detail component our movie at a component are going to show up without the menu is that making sense what this is doing because we're we really want that is right there how do we get that right there well there are numerous ways to handle it the easiest way to handle it is lazy loading and we should be doing lazy loading anyway so let's take talk about that I like to represent lazy loading with this image and the reason is sometimes we think of lazy like a lazy Sunday afternoon and a hammock with our favorite beverage but really lazy is more like this guy he's being lazy right now but he's really super fast we know when we build our applications it's going to build it into a bundle and if we aren't using lazy loading it's going to be one big bundle and when the user accesses our app they have to wait for that whole big bundle to come down to our to their machine to get processed by the browser before that first page will appear so what we want to do with our feature modules is we want to make them lazy loaded so what the when we build our application it will actually bundle each feature each lazy loaded feature into its own bundle ok that means when the user first hits the application only the little app module needs to come down the other modules then can come down asynchronously in the background or they can come down on demand depending upon how you have your lazy loading set up so how do we set up lazy loading well what we do I'm going to go back for a moment if you look at the all of our paths start with the prefix movies movies movies movies movies edit movies ID and so on so what we're going to do here is we're going to pull that movies path off specify at a notice here we're right in the correct place right under our shell component as part of the children and we're going to specify low children which is telling it to do lazy loading and we give it a string the reason we give it a string is because we do not want any references to our movie module in our app component anymore in our app module anywhere in our main bundle because we don't want the the build process to pull in the movie module as part of our first initial app module in the string we specify the path and we give it a hash and then the name of the class so our class was called movie module thank you then now we have our routes notice that the paths no longer contain movies because we had pulled that part off and now our router module for child will work because this tells it exactly where to put them and that's it so did anyone have at least one of those end things that they didn't know or hadn't thought about quite the same before yay okay so for more information you can reach out to me on twitter the code is a full code for the sample application that goes with this you can get off my github my slides are here and i also have a course on Pluralsight angular routing that you can find there I have free cards for a month on Pluralsight if you don't have a Pluralsight membership and with that I want to thank you all very much you
Info
Channel: ng-conf
Views: 50,003
Rating: 4.9455252 out of 5
Keywords:
Id: LaIAHOSKHCQ
Channel Id: undefined
Length: 21min 55sec (1315 seconds)
Published: Thu Apr 19 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.