Listing and Filtering User Watchlist Items
In this lesson, we'll take our movie filter, and learn how we can reuse it to display a filterable list of the user's watchlist movies.
- Author
- Tom Gobich
- Published
- May 10
- Duration
- 7m 31s
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
Listing and Filtering User Watchlist Items
-
(upbeat music)
-
So now that we can add movies to and from a user's watchlist,
-
let's go ahead and add in a list
-
of what the user has within their watchlist.
-
And we'll add the button to get to this page
-
right up here next to the logout.
-
But first we need to define the route and the handler.
-
So within our watchlist controller,
-
we can scroll on up to our index page
-
and we'll want view and we're also gonna want auth
-
so that we can grab the authenticated user.
-
Right now let's just return view.render
-
and let's scroll down to our pages here to see what we have.
-
There's a couple of different places that we could put this.
-
We could put it inside a movie's watchlist,
-
we could do user's watchlist,
-
or we could just put watchlist out here with our home.
-
Since this will be our one and only page for watchlist,
-
I think probably putting it out there with home
-
is gonna make the most sense.
-
So we'll just do pages/watchlist for our render there.
-
Let's save that real quick
-
and let's go define the route for it.
-
So above our toggle here,
-
let's do router.get/watchlist.
-
I'm gonna leave the S off of this particular route
-
because it will make a little bit more sense for the user
-
since they have that one and only watchlist.
-
Whereas with our post here,
-
it makes a little bit more sense
-
because that's a resourceful action.
-
Then we'll point this to our watchlist controller
-
and our index method inside of there is watchlist.index.
-
We'll keep with the resourceful naming
-
for the actual route name
-
as that won't be user-facing in any way.
-
Now that we have that, let's dive into our navigation
-
and add a link to that page
-
when we have an authenticated user.
-
So this will just be an ahref to our route,
-
watchlists, index, and we'll just call this link watchlist.
-
Then we're gonna want these two
-
to display beside each other.
-
So let's go ahead and wrap it in a div
-
and a class of flex item center gap of maybe three
-
and that div, give this here an indent and that div.
-
And we also have our button text here is text extra small.
-
So let's go ahead and apply that to our link here as well
-
so that they are the same size.
-
All right, give that a save.
-
Jump into our browser real quick just to check it out.
-
And okay, let's also copy that hover padding on that as well.
-
Looks like that might actually just be within our CSS.
-
So let's dive into our CSS real quick.
-
Nav A, let's just apply that to nav button as well.
-
Okay, just check that out once more.
-
There we go, that's a little bit more uniform.
-
So we can't click on this quite yet
-
because we haven't actually created the page.
-
So let's do that next.
-
So within our pages directory, let's right click that,
-
new file, watchlist.edge, hit enter there.
-
And one thing I think would be really nice for this page
-
is if we took what we have for our filters for our movies
-
and apply that to the watchlist as well.
-
So let's go ahead and use our movie index page,
-
which has our filters within it
-
as the base point for our watchlist.
-
Scroll up to the top.
-
We'll change our meta description here
-
to something like movies in your watchlist.
-
Scroll down a little bit
-
because we should also have an H2, there it is.
-
And we'll do the same there.
-
So movies in your watchlist.
-
Give that a save.
-
And let's jump back into our watchlist controller
-
because we need to finish out our index method.
-
Now for this, we can go ahead and use our movies controller
-
as a starting point here as well.
-
So we really just need to give everything here a copy
-
and we'll paste it and replace everything that we have
-
within our index method so far.
-
Updating the view render path to watchlist.
-
Scroll up a little bit here
-
because we will also need our request
-
and we can hit command dot on one of the red squigglies
-
and add all missing imports.
-
Looks like it didn't quite know
-
where to get query string from.
-
So let's try hitting command dot there and there it is.
-
So let's import that.
-
Okay, let's make sure everything's nice and happy.
-
Looks like it.
-
So let's give this a save real quick
-
and give our watchlist page a click
-
just to check and make sure that everything works.
-
And okay, cannot resolve the page
-
at pages watchlist.edge.
-
I wonder if I misspelled it again.
-
Let's go scroll down and see.
-
This time I didn't forget the L but I did forget the T.
-
All right, let's rename that real quick.
-
Can't fix that.
-
Let's jump back into our browser and try that once more.
-
There we go.
-
Okay, so next up we need to filter this down
-
to just movies in our watchlist.
-
So we could dive into our get filtered method
-
and make that change in there
-
but then it would also apply to our movies index page
-
where we're also using this method.
-
We could add in an argument
-
specifying whether or not we want to filter it
-
to just our watchlist movies
-
or we could define another method
-
but there's an alternative approach I think
-
would be a little bit more reusable.
-
So if we dive into our get filtered method,
-
I think what would be most useful
-
is if we just left this to getting our filtered
-
and we move the pagination back into the controller.
-
So if we remove the paginate here,
-
that's going to allow us to apply additional
-
filter statements to this query
-
within the controller itself,
-
making this method a little bit more reusable.
-
So we'll remove the page and the paginate,
-
give that a save once more so that it formats.
-
If we take a look real quick,
-
no red squigglies as we're only being used
-
for the pagination method.
-
Let's first go ahead and dive back
-
into our movies controller
-
and fix the index method up there real quick.
-
So if we scroll up,
-
we no longer want to supply the page into there.
-
And if we temporarily remove the await here
-
and we take a look at the type of our movies,
-
it's now our model query builder contract.
-
We're no longer executing the query
-
since we're not awaiting it anywhere,
-
meaning that we can now do .paginate
-
directly off of our get filtered call
-
as the page number in
-
and specify that we want 15 per page.
-
Now we no longer have that default one
-
that we were applying within the parameter defaults
-
of our get filtered call.
-
So we do want to provide that default here
-
with our request.input as a default value of one there.
-
And then we just need to add the await back.
-
We'll remove that for demonstration purposes.
-
So everything here should be behaving
-
the exact same as it was before.
-
We just move the paginate from inside of our get filtered
-
to now outside of our get filtered.
-
So we want to do that exact same thing
-
within our watchlist controller as well.
-
So remove page there,
-
add in a default page of one on our page,
-
input .paginate, specify the page and save 15 per page.
-
Now, before we take this any further,
-
let's go ahead and dive back into our browser,
-
give it a quick refresh just to make sure
-
that everything still works and it does.
-
Hide that back away.
-
And specifically what that refactoring allowed us to do
-
is now we can break this down
-
and do an additional where has
-
to filter these results down beyond
-
just our get filtered call.
-
So now we can do a where has with watchlist
-
and specify that we only care about the watchlist
-
where query.where user ID is the current auth user ID
-
and our exclamation point there.
-
Now, since this is our watchlist controller
-
and we're going to place an auth middleware on this
-
to require a user to be authenticated
-
in order to get in here,
-
we don't need that if statement wrapping this where has.
-
So we're a-okay to leave this as is.
-
We'll give that a save real quick.
-
And now if we jump back into our browser,
-
give it a refresh,
-
we should only get back movies
-
that are in the user's watchlist,
-
which is exactly what we get.
-
Cool.
-
So the next thing that we need to do is update our form
-
because currently if we were to submit it,
-
it's going to take us back to just our movies index page
-
while we want to be on the watchlist page
-
after we apply a filter.
-
So let's hide that back away,
-
jump back into our watchlist page,
-
and we should just need to update the action here
-
from movies.index to our watchlist.index.
-
We also need to apply that to the base URL as well.
-
So if we jump back into our watchlist controller,
-
scroll down a little bit,
-
the base URL right here,
-
we need to switch that to our watchlist.index too.
-
Give that a save.
-
Now, if we jump back into our browser
-
and try to search by movies with a title containing S,
-
search that, we get back just to,
-
saving private Ryan and stay.
-
If we remove that, run it again,
-
nope, looks like our validator there
-
doesn't like an empty value for that.
-
Probably need to add nullable to that as well.
-
So let's go scroll up to our validators real quick,
-
go into our movie validator,
-
movie filter validator,
-
and let's see, that was our search field.
-
So we have that as optional.
-
Probably also need to just make that nullable.
-
Let's give that a try.
-
Jump back into our browser,
-
try removing that once more,
-
search, nope, still doesn't like that.
-
Okay, well, let's go ahead
-
and just remove this off a numeric.
-
It may be missing up the optional check that we have.
-
Give that a save there.
-
And now if we run this without our title search,
-
everything should be happy.
-
There we go.
-
See, we have one movie in post-production.
-
I'm your boogeyman.
-
So we'll go ahead and do a post-production search there.
-
All right, let's do a released
-
and now put I'm your boogeyman should not be included.
-
Cool, so everything seems to be working a-okay.
-
Let's go check out our pagination real quick.
-
So make sure that that's going to the right page,
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!