2.6 Using Dynamic Routing and Query Strings
In most data-driven apps, we don't know all the URLs ahead of time—they are dynamic. Fortunately, Express's routing engine makes it very easy to set up dynamic routes. We'll look at how to set them up and how to work with the query string in this lesson.
1.Introduction3 lessons, 20:17
2.Building a Web App6 lessons, 1:01:23
3.Middleware and Routers2 lessons, 16:36
4.Conclusion1 lesson, 01:31
2.6 Using Dynamic Routing and Query Strings
In the previous lesson, we added a guitars endpoint so that we could view our list of guitars. And in this lesson, we are going to add a details page so that we can view the details of an individual guitar. And we will access that page in two ways. Originally, we were just going to use the id as a segment in the URL. And we will still do that, but we are also going to use the query string because really we need to know how to do both things. Now, it looks like that this worked at first glance, but it didn't. Notice that we have the index here, and we will talk about why here in a few moments. But to start, we will create our view. And we're going to use the index view as a basis because that has most of the markup that we need. So let's just copy and paste. Let's rename this to details.ejs. We do not need the forEach loop, so we can get rid of that. And let's move the guitar.name from this h4 down here to the h2, because that is the title of our page. And you know what, let's also add the name up here to the title. And really, what we should do is do the name, and then My Guitars. That should work, okay, so now we just need to display all of the other information. So let's add some labels, so that we will have the Manufacturer, followed by the actual manufacturer, we will have the Year. And then we have just some other pieces of information, like the neck material, the fingerboard material, and the amount of frets. So we'll say Neck, and then Fingerboard, and then the Frets. And we will change those properties so that we pull in the correct information. And then we will be done with this view. So there we go, if it doesn't work, we will find out. And let's close that and be done. And let's also go ahead and open up the, well, we have the index open. Let's add a link here for the name of the guitar so that we can navigate to that page. We are going to use the URL segment here. So we'll have guitars/ and then the id. So we will get that id using our guitar object, the id property, and that will be good to go as far as that is concerned. We will put the name there, and we should be done as far as this view is concerned, so let's close that. Now, as far as our code is concerned, we are going to have two routes here. The first route is going to be the guitars route that we wrote in the previous lesson. But we also need to include the code for retrieving the query string here. Because that is what's going to be matched with this route. So we'll start here, and then we will add a route for having the id as a segment in the URL. So let's first of all retrieve the id. We have our request object, it has a property called query, and this gives us access to the query string parameters. So we have one called id, and then we have that value. So then, if we have a value, then that means that we want to retrieve the individual guitar and display the details. So let's get our guitar from the repository. We'll use the getById method, passing in the id. And then we will use the response. We will render our new details view. And then the data that we will pass is the guitar. So we have this code, let's make sure that it works. So let's just refresh this, since this is what was here. And there we go, we have the individual page, and that's what we wanted. Let's check something else, an id of 3, we have that guitar. So let's do an id of 6. Now, we don't have one with an id of 6, so let's see what we get. Well, we get the index, which is what we got before we implemented the code for handling the query string. So let's look at why. Let's go to the command line. And we see that there is an error, Cannot read the 'name' property on null. And why did that just jump up, I don't know. But there we go, Cannot read property 'name' of null. Now, the way that the repository works, if the guitar doesn't exist with the given id, then it returns null. So we of course don't have a guitar with an id of 6, so null was returned. And when null was passed to our details view, it tried to use the name property on null, which is impossible. [LAUGH] So what happened, this had an error. So our method continued to execute to line 13, where it rendered the index view. And that's why we see the result of the index here. So really what we need to do is check to see if we don't have a guitar here. Because if we don't, then there's nothing to display. It doesn't exist, it's a 404. So we use our response object. There's a method called sendStatus. And then we pass in the status code that we want to send, in this case 404, and that fixes that. So if we try this again, we see that that is Not Found, which is what we wanted. Great, so we have handled the case where the id is in the query string. Now, we need to handle the case where the id is part of the URL path. So our route is going to look very similar, we start with guitars. And then we hard code it. We say 1, and this means that we are going to have a route for 1, and then one for 2, and then one for 3, and 4, and 5, and 6, and however many guitars that we have. No, I'm kidding, that's awful. We can't do that, that's impossible. Because if you have an actual data store, you never know what that id is going to be. So instead, what we have is called a URL parameter. You can think of it as a parameter to a function. So we denote a URL parameter, starting with a colon, and then a name, id in this case. So this means that we are going to have a URL parameter called id, and we access it almost exactly like the query string except that instead of using query, we say params, and then whatever name we used. So req.params.id gives us the value that is in this segment of the URL, and then we just do everything that we did before. We attempt to retrieve the guitar, if it exists. Then we return that view, otherwise we return a 404. So let's make sure that this works. Let's go to /1, we see our page, but our image is not displayed there. So let's open up that view. The path is wrong because we are a bit deeper as far as the path is concerned with our URL segment. But we can fix this by getting rid of that dot. And we will be good to go there, so there we go. And if we say /2, then we will see that. If we say /6, we should see Not Found, which is what we would expect to see. Now, let's make sure that our URLs work here for the index, and they do. So everything is working okay. The last thing I want to do, however, is since we have some replicated code, I want to write a function that would then do basically what we've already done. So let's call this sendDetails, and we will have the id. We will also have the response because we need to do stuff with the response like render our view. So we are essentially going to do what we have up here. We're going to get the guitar with the id. If it doesn't exist, we return 404. Otherwise, we render that view. So we can get rid of that code and just call sendDetails. You can pass in the id, response, boom, we're done. And then as far as our other route, we can get rid of pretty much everything. And instead of creating this id variable, we can just use the req.params.id. That will clean that up, and we are good to go there. So one last time, let's make sure everything's going to work, and that does. Let's make sure that the Not Found works, that does. Let's use the query parameter with an id of 3, we see one guitar. Let's do id of 100, Not Found. Everything works as it should. So in this lesson, you learned how to handle the query string, at least retrieve values from there. You learned how to send a status other than 200. So if you wanted to send a 500, [LAUGH] in this case, you could if you wanted to. But using the response object, you now have the sendStatus method. And you also learned about URL parameters and how to retrieve them so that you can display dynamic data.