Check out a free preview of the full Angular 17+ Fundamentals course

The "Dynamic Routing Exercise" Lesson is part of the full, Angular 17+ Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Mark goes through a routing recap, combining multiple elements together. They set up links, enable routing, and ensure the router outlet is in place. They also demonstrate how to dynamically generate a list of links using the ngFor directive and the router link attribute. Finally, they show how to use a setter to retrieve the ID parameter from the URL and display the corresponding details.


Transcript from the "Dynamic Routing Exercise" Lesson

>> So we're in 08-routing-recap. So the reason I call it the recap, because when we do these, we usually will combine multiple elements together, okay? So we'll combine multiple elements. So we're gonna be working on getting some links set up when we work on enabling routing, and we're gonna be working on making sure that we have our router outlet in place.

And I believe in you all and I know you got this, you gotta cover it like a blanket. Let's do this. We're building, okay, I'm gonna go check the application. So the router recap is here but it's not doing anything, all right? So we can just do better.

We just do better. Let's start with the first step. First that was close this up so it's more clear. Okay, so we got router-outlet, looks good. So in an app.routes.ts, define a route for HomeComponent as the default route. So we'll do that now. So I'm in 08-routing-recap, source app, app.routes.

Okay, so we need to do that first one. We use our syntax for a route, excuse me, and we'll do path. Because it's default, it should be the empty string, okay? Now what's the component we should go to? Somebody yell it out for me.
>> HomeComponent.
>> Perfect, HomeComponent.

Make sure it's the one from your current project. That way it doesn't get us all mixed up like it did earlier. We got that. Okay, so we did our first step. So we're in app.routes.ts, and we set up our HomeComponent. Okay, excellent. Now we define routes for DetailsComponent, all but we're gonna add a URL parameter.

So remember that placeholder, okay? So let's do that. So I'm gonna take this string for you and we're gonna go back to app.routes.ts. We're gonna add another entry to our routes array. We call it path. Okay, okay, okay, look at that, and we got component. And what component should it be?

>> Details [INAUDIBLE].
>> Yeah, there you go. You cooking. You smell that? Cuz only her cooking, I like that. Yeah [LAUGH] I'm so sorry. I can't control myself. All right, now, so we done the first two things, our routes are defined. We have one standard route, and then we have another route that has a URL parameter, that placeholder colon ID.

So that is part of our story. So in app.component.ts, we need to add our router-outlet. So let's go to app.component.ts. Okay, so we have RouterOutlet there. It's already importing for you, you're welcome, I care about you, I know. But man, he's so nice, I am so nice. I put that there for you.

All right, but we do need to put our RouterOutlet. And as we discussed a few moments ago, it could really go anywhere but we'll put it right here, right, right under the h1. But it could be moved around as you desire. Okay, so here's what the error is.

On line 11, I have a forward slash as a part of the route definition. An angular routes cannot start with a slash. So to make this work, we'll delete that forward slash from our route definition in app.routes.ts. Okay, excellent stuff. So now, see, look at that. All right, so now we can go on to the next step.

So I'm back at the README, and now we're working on updating our components. So in app.component.ts, dynamically generate a list of links for products in productTitles. How do we dynamically generate a list of links? Or how do we dynamically generate a list to render? What's our tool for that?

>> For.
>> For, that's right. So this says to do it where though. We're gonna do this in upper corner. Okay, cool, so someplace, I'm gonna say do it between the h1 title tag and the router-outlet, right? Because you probably want the list of links, and then when you click them, the content is displayed below.

So let's do at for, and we got, so we'll say, title, maybe, of productTitles. We'll track productTitles. Well, we would track title, excuse me. Now we gotta make those links. So we gotta make a link. So I'm just gonna do this just because I like to get something working.

So in general, whenever I'm solving any problem, I like to get something working before I spend too much time going deep into the details, because then I don't know where I failed on the path. So let's just get the links working without the fancy stuff, right? So I'm gonna do title and just make sure I can get that to display and see what happens.

All right, that looks good, that looks good. But you notice what I noticed? I left this in big for some purpose, for you to solve this any way you want to. They're all on the same line, probably hardest to read. So you could do a list or you could do a p tag, something with a block level.

Styling, you got a lot of choices. You do whatever you want here, okay? I'm just gonna make it easy for myself and just do a p, okay? Optional, but I'm saying what I'm doing, okay friends? So back in, so now, you see, so I got a p wrapped around.

Here, let me get that out of there. Okay, there you go. So you all can see it without it highlighting everything. Okay, so I got that p wrapped around that a tag, okay? So all that does is make it in the straight line so I can see it more clearly.

Okay, now we got RouterOutlet. I already know what we need next, but I'll tell you. Okay, see, we need the routerLink attribute. Remember that? So you get routerLink. But for it to work, you gotta import RouterLink. Okay, I'll let you catch on that part. You import Routerlink, and then you gotta set it to be a value.

Okay, we're not all the way there yet, we gotta continue going. So here's what we want. So when you do on a routerLink and you do in a parameter, like URL with the parameter, you gotta give it two parts. You gotta say where you wanna go and what parameter you wanna use, okay?

So first, where do I wanna go? Anybody remember? What page this goes to? What route?
>> Details.
>> Details, very nice, I like that. That's where I wanna go. And then I need a value here. Right, I need a value. So here's how we're gonna sort it out for now, okay?

If they're gonna sort out you can use this thing called index. This is a value that's available within the scope of our for, okay, $index. It's available within the scope of the for. It just provides it for you, okay? So now, Do we have to, I think we gotta wrap this in square brackets.

Okay, yeah, so the way you use this thing, right? There you go. There you go, now we should be able to. Yeah, there you go, cool. All right, so we're pretty close. Okay, but I'm gonna go back here so you can catch up with me there. So we had to put our routerLink.

And remember what I told you about binding to things. It's universally true, but we'll see one context where it'll be like, I thought I should bind but I didn't. In this case you had to bind, because if we didn't bind, guess what happens? The right hand side is a string.

How did I know that it was a string? Let me show you. Well, if I take this off, you see the kind of color changed. So the IDE was telling us the hint right there, that what was being sent to routerLink was a string value. You see, but you can't.

And then once I put the bindings it's like, this is actually a value which represents the path. And then we got that index. If you want to see that index, just so you can see, right? I'm just gonna put this, you don't have to type this, I'm just gonna show you.

So you see what the values of the index is. It's like, there ain't no value. Okay, hold on. All right, there you go, interpolated. You see? So it's just the indices of the array, like your i, your iterator value. There you go right there. You could do a dollar sign index in your for, okay?

Fantastic, we are cooking. We are out here hotter than fish grease right now. Stop playing, all right? We did this, we did that, so now we're in the DetailsComponent. Now we gotta do that setter thing, okay? And that syntax is a little tricky in the beginning so I gave it to you in the next step so you can just get it to work, cuz I don't want you to spend time trying to remember that.

Oops, sorry, I want you to spend time working on that. So let's do that. So let's go to details. So let me just recap where we are cuz we've done a lot of steps, recap where we are so far. What we've done, we've listed all of the products, and we made them links using routerLink.

We've defined a path in our routes.ts that has a placeholder for the productId that we're talking about that we wanna reference. Now the step is to go into details.component.ts and create that productId. Okay, now we wanna create that productId. So let's go to there. So we go to details.component.ts.

So we got some products in here. All right, that looks good, that feels crisp. First thing we're gonna do, we need the productId. Now I set this to -1, you know why? Cuz it's just a way to represent that it's not there, but I don't wanna do undefined because you know TypeScript do not like undefined.

And no, TypeScript gets really angry. So I just do [LAUGH] -1. Somebody in the comments tell me if that's wrong, that's fine, I'll adjust my behavior. But the next thing we need to do is get to this input. We gotta get this input going, okay? And I'll explain this code again cuz I know we went through it but it's still new behavior, all right?

So I'm gonna import it. Okay, let me save, and let's make sure we have some decent spacing. So I have an input called id, but I use a special JavaScript thing called set, right, to make it a setter. Okay, it's called a setter. You can have getters and setters.

This is a setter. Okay, and then I say, set the id. Stop with the help, I don't want the help right now. Host of the Id, and then you got a value, because it's a setter, it takes the value. You see, that's why you can set the value for this thing.

Why is this setter interesting? Think about it like this. What if you wanted to transform the value being passed in any format you want to do, right? You ask someone for a username, and you wanna change it to all lowercase or something before you do the final assignment.

That's why you have a setter here, right? We have a chance to do something before we set the value of our input versus just taking the value and assigning it, okay? This just gives us a chance to do something. And we do wanna do something. We wanna actually take that parameter URL and we wanna assign it to our productId.

That's all we wanna do.
>> Is it this.productId or this.Id?
>> No, it's productId because that's this property right here. I'm gonna try something in the minute cuz I wonder if we can get away because it's just. Well, this becomes a string. We'll think about it. Cuz I'm wondering, is there even smoother syntax to this?

No, I'm just thinking about it out loud, I like to experiment with stuff. Okay, but first, let's continue our story and then we'll come back to that. We'll see if there's even a smoother experience. Okay, so we got our product list. Looking good, feeling great, how are you?

[LAUGH] That is the data. All right, so we got that, now we just gotta update the details. Y'all know how to do that already, right? Y'all know how to update the details. So go ahead and knock that out. So we'll say, we want this., and we have product list.

Dot, whatever thing we want, that's what, title. Okay, we're gonna put that in our curlies. Oops, that's too many, super curly. Okay, we got this.producList., what's the next one, price, I think. I don't remember what the other property is.
>> [INAUDIBLE] Your index into that array?
>> You jumped ahead of me, cuz I told you the I knew it, I saw that earlier.

>> These are red squiggles.
>> I know where I was gonna, well, so I'll get to that now. I was hoping someone would call that out, that's actually exactly what I wanted you to do. So that way we could talk about the difference of what's supposed to happen.

Because right now productList is an array, but we want an individual element from that array. What do we do here? We gotta use that, the indices. Is still an array even though we're in [INAUDIBLE], because sometimes what can happen is that when you start working within a framework, you kind of lose the distinction between what's specific to the framework and what's just programming, what's just JavaScript.

This is just JavaScript stuff right now, or TypeScript in this case. So your same logic which is totally right, we gotta get that ID but we can do productId. Okay, we get productId, which is super red. ProductId, and then productId. Okay, we save this, just understanding of what's happening.

Let's display. Before we get to displaying anything else, can we display productId? Because what if the ID is just a value that we don't know about or something we aren't expecting? Okay, -1 is the first one. I think that's what our problem is cuz I said it's a -1, but I thought this input was supposed to happen before that, which makes me feel some type of way.

So if I do 0 here, it fixes it. Okay, that's Python that you can do -1 and it wraps around. This is annoying to me.
>> Mine's working with -1.
>> It is, mine is not, mine is like, no. That's okay, it is fine, but at least you know if you had that weird issue without displaying anything.

Here's what I want to check out. So here's what I want to experiment with, with angular. Can I do at inputs of ID without the setter?
>> Did you say we had to add something, an additional component in order to do these input setters? Did we do that, or am I thinking of the slides?

It did add something else in addition to the routing to be able to pass this parameter.
>> That's why yours is working and mine isn't, cuz you followed the directions. You're totally right. Okay, let me explain my thinking behind why I was so perplexed. So I said something under my breath but I'll explain it to you outwardly.

Okay, there's an order of operations in angular called the life cycle of a component, right? There's an order. Same thing like React has life cycles, we have life cycles. Your inputs are bound before the template is rendered. The -1 shouldn't matter because I should get the value before it renders through our input.

You see, I'm saying I thought the input should be done first but I was like, why is it not working? That's why it's not working because I skipped a step of providing. Wow, good catch, look at you go. You know what, let me tell you something, I like people like you, bringing in the value, okay, no seriously.

Cuz we have to provide, is called provide components something, input binding inputs. [INAUDIBLE]
>> Something, yeah, I knew there's something like that, yeah, withComponentInputBinding. Yeah, so provide router withComponentInputBinding. Yeah, so it's supposed to read like that, right? So the sentence is supposed to read, provide the router, these routes, withComponentInputBinding.

Yeah, there we go, that's what I was missing. Good catch, I like that energy cuz now it should all be what we're hoping for. Yeah, you see? Yes, everything is, we're into money. We're in the money, way to cook together team. Look at that, withComponentInputBinding. Just to reiterate what happened here is that without this, it wasn't binding our value for the input, so it wasn't setting it.

So it was using -1 and then it was just trying to access an array with -1. But guess what happens with the arrays? So I'm gonna let this list = [1, 2, 3], right? So this is just a list. So if I do a list, okay, list.length, right?

Everything, length. Okay, so we agreed it's just a list, that there's nothing special about this list. Neither was there about our product list. So if you do this and -1, you see what it gives you? Undefined, so that's how we were getting that undefined. But I feel like there's a proposal right now for JavaScript, that they're gonna change this, that -1 will be the end of the list by default.

Cuz in Python, I think you can go negative index. I actually know you can in Python. Ooh, router-recap, that was a big one. Lot of little moving parts, easy to get tripped up.
>> We finally got it good in the chest [LAUGH].
>> All right, that's what I'm talking about.

Since you're doing good, I got something for you. I'm gonna say, [INAUDIBLE] it's bow, that's for you, okay.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now