Loading A Movie Using Route Parameters
In this lesson, we'll learn how we can reuse a route definition using route parameters to show any item we have for our movie resource.
- Author
- Tom Gobich
- Published
- Jan 24
- Duration
- 9m 17s
Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.
Adocasts
Burlington, KY
Transcript
Loading A Movie Using Route Parameters
-
(upbeat music)
-
- 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.
-
Introduction
-
Fundamentals
-
2.0Routes and How To Create Them5m 23s
-
2.1Rendering a View for a Route6m 29s
-
2.2Linking Between Routes7m 51s
-
2.3Loading A Movie Using Route Parameters9m 17s
-
2.4Validating Route Parameters6m 6s
-
2.5Vite and Our Assets6m 38s
-
2.6Setting Up Tailwind CSS9m 5s
-
2.7Reading and Supporting Markdown Content4m 32s
-
2.8Listing Movies from their Markdown Files8m 51s
-
2.9Extracting Reusable Code with Services7m 4s
-
2.10Cleaning Up Routes with Controllers4m 52s
-
2.11Defining A Structure for our Movie using Models9m 38s
-
2.12Singleton Services and the Idea of Caching6m 11s
-
2.13Environment Variables and their Validation4m 16s
-
2.14Improved Caching with Redis10m 44s
-
2.15Deleting Items and Flushing our Redis Cache6m 46s
-
2.16Quick Start Apps with Custom Starter Kits6m 28s
-
2.17Easy Imports with NodeJS Subpath Imports8m 40s
-
-
Building Views with EdgeJS
-
3.0EdgeJS Templating Basics8m 49s
-
3.1HTML Attribute and Class Utilities6m 9s
-
3.2Making A Reusable Movie Card Component10m 24s
-
3.3Component Tags, State, and Props4m 53s
-
3.4Use Slots To Make A Button Component6m 56s
-
3.5Extracting A Layout Component5m 13s
-
3.6State vs Share Data Flow2m 59s
-
3.7Share vs Global Data Flow6m 7s
-
3.8Form Basics and CSRF Protection6m 13s
-
3.9HTTP Method Spoofing HTML Forms3m 3s
-
3.10Easy SVG Icons with Edge Iconify7m 57s
-
-
Database and Lucid ORM Basics
-
4.0Configuring Lucid and our Database Connection4m 3s
-
4.1Understanding our Database Schema9m 35s
-
4.2Introducing and Defining Database Migrations18m 35s
-
4.3The Flow of Migrations8m 28s
-
4.4Introducing Lucid Models5m 43s
-
4.5Defining Our Models6m 49s
-
4.6The Basics of CRUD11m 56s
-
4.7Defining Required Data with Seeders11m 11s
-
4.8Stubbing Fake Data with Model Factories13m 48s
-
4.9Querying Our Movies with the Query Builder15m 30s
-
4.10Unmapped and Computed Model Properties3m 24s
-
4.11Altering Tables with Migrations7m 6s
-
4.12Adding A Profile Model, Migration, Factory, and Controller2m 57s
-
4.13SQL Parameters and Injection Protection9m 19s
-
4.14Reusable Query Statements with Model Query Scopes8m 11s
-
4.15Tapping into Model Factory States9m 15s
-
4.16Querying Recently Released and Coming Soon Movies4m 59s
-
4.17Generating A Unique Movie Slug With Model Hooks7m 59s
-
-
Lucid ORM Relationships
-
5.0Defining One to One Relationships Within Lucid Models5m 49s
-
5.1Model Factory Relationships2m 54s
-
5.2Querying Relationships and Eager Vs Lazy Loading5m 17s
-
5.3Cascading and Deleting Model Relationships5m 16s
-
5.4Defining One to Many Relationships with Lucid Models6m 56s
-
5.5Seeding Movies with One to Many Model Factory Relationships5m 24s
-
5.6Listing A Director's Movies with Relationship Existence Queries8m 41s
-
5.7Listing and Counting a Writer's Movies8m 41s
-
5.8Using Eager and Lazy Loading to Load A Movie's Writer and Director5m 18s
-
5.9Defining Many-To-Many Relationships and Pivot Columns9m 48s
-
5.10Many-To-Many Model Factory Relationships4m 50s
-
5.11A Deep Dive Into Relationship CRUD with Models18m 5s
-
5.12How To Create Factory Relationships from a Pool of Data13m 55s
-
5.13How To Query, Sort, and Filter by Pivot Table Data9m 47s
-
-
Working With Forms
-
6.0Accepting Form Data12m 15s
-
6.1Validating Form Data with VineJS9m 29s
-
6.2Displaying Validation Errors and Validating from our Request7m 16s
-
6.3Reusing Old Form Values After A Validation Error2m 3s
-
6.4Creating An EdgeJS Form Input Component5m 28s
-
6.5Creating A Login Form and Validator5m 1s
-
6.6How To Create A Custom VineJS Validation Rule9m 7s
-
-
Authentication & Middleware
-
7.0The Flow of Middleware7m 49s
-
7.1Authenticating A Newly Registered User4m 14s
-
7.2Checking For and Populating an Authenticated User2m 10s
-
7.3Logging Out An Authenticated User2m 24s
-
7.4Logging In An Existing User6m 54s
-
7.5Remembering A User's Authenticated Session6m 55s
-
7.6Protecting Routes with Auth, Guest, and Admin Middleware5m 36s
-
-
Filtering and Paginating Queries
-
8.0Creating A Movie List Page3m 43s
-
8.1Filtering A Query By Pattern Likeness7m 9s
-
8.2Filtering Our List by Movie Status5m 47s
-
8.3How To Apply A Dynamic Sort Filter To Your Query7m 12s
-
8.4Joining SQL Tables To Order By A Related Column4m 49s
-
Validating Query String Filter Values7m 23s
-
How To Paginate Filtered Query Results9m 15s
-
Pagination First, Last, Next, and Previous Buttons4m 2s
-
-
User Watchlist
-
An Alternative Approach to Many-To-Many Relationships4m 56s
-
Toggling A Movie in an Authenticated User's Watchlist9m 56s
-
Listing and Filtering User Watchlist Items7m 34s
-
Allowing Users To Toggle A Movie As Watched4m 44s
-
Filtering By User's Watched Status6m 7s
-
Defining A Composite Unique Constraint4m 46s
-
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!