Transcript
-
- So at this point, we should have some understanding of how the route system's gonna work within our application, how we can reuse the same URL for a route
-
using different HTTP methods to make up what's called a resource that allows us to perform different actions against said resource. But at this point, we only know how to hard code particular routes,
-
but we might have a database of thousands or even millions of different movies. And whenever it comes to our route definitions, we're not gonna wanna have thousands or millions of different routes
-
defining each individual movie that we have. That's just not realistic. So how can we replace my awesome movie with some unique identifier
-
that allows us to reuse our movies.showRoute for any one individual movie that we may want to show so that we don't have to copy and paste
-
this particular route thousands or millions of times? Well, that's where route parameters come into play. A route parameter can kind of be thought of as a placeholder within our routes definition.
-
So let's go ahead and take a look at what that looks like. So we can replace my awesome movie here with a route parameter, let's call it slug, because that's kind of what we have within the string right here.
-
A slug can be thought of as a URL safe, unique identifier. That's also human readable. To define a route parameter, we wanna start the parameter with a colon,
-
and that's gonna tell AdonisJS, hey, we're entering in a route parameter here, and that's gonna help Adonis match up our route whenever we make our requests. And then after the colon, we just wanna give our parameter a name,
-
which we can call it slug. At this point, if you recall back to when we were taking a look at our HTTP context, you may remember that we had a params object on it.
-
So we can try to do ctx params, and we can do dot here, and you'll notice it doesn't pick anything up. If we take a look at the type for our params, it's just a record string any,
-
which we previously learned is essentially just an object where the string is our key, and any is the underlying value. Well, we know that we've called our param slug.
-
So let's try to do params.slug. Let's give this a save. And on our movies detail page, we're already providing movie directly into our H1. So if we jump into our browser at this point
-
and give it a refresh, uh-oh, we get an error. Cannot make URL for slash movies, slash, and then our slug param route. It says it's missing a value for slug param.
-
And then if we scroll down just briefly here, it states that the error is happening within our resources, views, pages, movies.edge, line number 13. And that's where we're creating and injecting the URL
-
for our navigation. Whenever we generate out a URL that has a required route parameter within it, we have to define that route parameter to the route in order for it to successfully
-
generate out the URL for that route. So let's hide our browser back away. And we know that the error is within our navigation. Specifically, it happened on our movies page, but that's just because that's the page
-
that we were trying to render. It exists too on our homepage. Within the route method, the way that we can specify a route parameter for the underlying route that we want to generate is via the second argument.
-
We can provide a key value pair here where the key is the parameter name and the value is the parameter value. So our parameter name is slug and our value is my awesome movie.
-
Well, at this point, the name for our navigation item's a little outdated as well. So let's switch this to my awesome movie because that's the specific movie that this route will render out.
-
Let's copy our navigation once more and let's apply this into our movies page as well. So paste it in here. And now if we jump back into our browser, let's give our page a refresh and cool.
-
So now we see my awesome movie, but instead of being valid English, now it's just rendering out the underlying slug that we have. If we try our navigation, we can go home and we can jump back to my awesome movie again.
-
However, in our URL, since my awesome movie is now dynamic, we can replace this with whatever we want. So this could be another awesome movie and look at that, it worked just fine. But if we click my awesome movie,
-
that's always gonna take us back to my awesome movie because that's the underlying slug that we're providing whenever we generate out this particular route. If we wanted to, we could copy this link, paste it in here.
-
Movies.show would remain the same, but the slug would change from my awesome movie to another awesome movie. We can update the text for that there as well. We can give that a copy
-
and paste that within our homepage too. If we jump back into our browser, now we have two links. We have my awesome movie and another awesome movie. We can click between these just fine and it will work. In most cases though,
-
you're not gonna want the user to be able to put just anything in here. You're gonna wanna actually be able to match it up to something that you have to render out some dynamic content because at the end of the day,
-
we're not just gonna wanna show the slug back to the user. Instead, we're gonna wanna show details about this particular movie. So how can we go about that? Let's go ahead and hide our browser back away. And within our resources,
-
let's add a directory called movies. So new folder, movies. For right now, we're gonna place some movies within here along with their details. So let's create a couple. We can do my awesome movie.
-
And for right now, we'll do this as just plain HTML. We'll have an H1 with my awesome movie. And then we'll just do a paragraph and let's go back to our extensions
-
and let's install an extension called Lipsum Generator. This is just gonna allow us to generate out quickly paragraphs of Lipsum text, which is just placeholder text.
-
We can do Command or Control + Shift + P to enter in our command palette where we can type in Ipsum and generate lorem ipsum text. For right now, we can just say generate out one paragraph
-
and then just hit Enter there as well. And it will generate out a paragraph worth of text. I've gone ahead and broken mine down in the separate lines. So it looks a little something like this. I'm gonna give this page a copy
-
and let's create another movie. So let's right click on movies, new file, another awesome movie.html. Paste this in here and let's just update the H1.
-
So another, and let's create a third. So we'll right click again, do new file, and we'll do awesome movie, the trilogy. Paste that in there, awesome movie, the trilogy.
-
So I'm gonna close each one of these HTML files out to clean our tabs up here a little bit. Let's head back into our routes. And now we wanna use the value within our slug route parameter
-
to fetch the underlying HTML from our movies. For this, we can use a new JS module. So let's import fs, which is short for file system,
-
from node colon fs. And let's do the promises version. Within our route handler, we can build out the URL to fetch our movie by doing const URL equals,
-
and we can use Adonis's app module and we can import that from AdonisJS core services app. And that specifically has a method called makeURL
-
that will allow us to make a URL from our applications route relatively simple. So from our applications route, we wanna go within resources, movies, provider slug,
-
and then our slug's not gonna contain .html, so we'll wanna add that in. So we can do resources, movies, and we'll wanna switch these to backticks so that we can inject the slug
-
directly into our file path here. So this is just ctx, rams, slug, and then lastly, let's add in the HTML file extension. And this will build out a URL object
-
pointing to the underlying movie that we provide into the slug, which means we can now use the fs module to read that file directly to get its contents.
-
So we can call this const movie equals await, reach for that fs module. Specifically off of this module, we want to read a file provided in the URL
-
that we just generated from the previous line, and then specify that this is an encoding type of UTF-8. Now within the data that we're passing into our pages movies,
-
we can remove the slug altogether and just pass in movie. We can give this a save now, jump back into our browser. Another awesome movie matches one of the files that we created within our movies directory.
-
So we should be able to give this just a refresh, and voila. So we see the underlying text that that makes up the body of the file that we're reading.
-
We have h1 right here, along with our paragraph text. But within here, we're seeing the actual HTML elements rather than those being rendered out. This is something that AdonisJS and EdgeJS
-
does for our safety. It's not going to just willy nilly plop any old HTML that we have saved within our system onto the page. Instead, we have to tell it that,
-
hey, this is safe to actually render out. And the way that we do that is, let's go ahead and hide our browser back away, and let's jump into our movies page.
-
We just need to replace the double curly braces with now triple curly braces. And this will tell EdgeJS, okay, don't escape the underlying code that we're trying to render out here.
-
Instead, just render it raw. And since we're going to be rendering raw HTML, we no longer want to wrap this within an h1 because it has an h1 within there itself. So now we can give this page a save,
-
jump back into our browser, and voila. You see it automatically updates. We have our h1 now, and our paragraph is also being rendered out appropriately. If we jump to My Awesome Movie,
-
we see My Awesome Movie's details, another awesome movie, and then there's the movie that makes this a trilogy that we don't quite have a link to yet, but we'll get there. Before we round out this lesson, there's one more thing I want to do
-
that finalizes the naming convention that we're using for our resource. So we have our URL using movies slug, which matches the resourceful naming, as well as the name itself, movies.show.
-
But our page path is still called pages/movies, which when you read it like that, sounds like we're going to be listing out all of our movies when in fact this URL is specifically
-
for showing one individual movie. Typically what I like to do is keep my pages naming in line with the routes name. So instead of just doing pages/movies,
-
instead we'd want to do pages/movies/show. So we can give this a save and let's jump into our pages directory and let's right click to add in a new folder called movies.
-
And then let's move our movies file into that folder. Go ahead and move it. And now let's rename it show, give that a save. And now if we jump back into our browser, we do see an error,
-
but I believe this is because it tried to render the page while we still had it called movies.edge before we actually gave the file a rename. So let's just try and refresh our page
-
and voila, there we go. So now it's working and we can jump between my awesome movie and another awesome movie and our homepage, A-OK.
Loading A Movie Using Route Parameters
We'll learn how we can reuse a route definition using route parameters to show any item we have for our movie resource.
Join the Discussion 4 comments
-
-
Responding to josemanuel
Hi Jose! We will be doing a series of API development a little later on, at the moment though, we unfortunately don't have any resources for this. However, the primary difference between this series and an API is instead of providing information into page state, you'd instead return it as a JSON response.
2
-
-
-
Responding to josemanuel
-