Toggling A Movie in an Authenticated User's Watchlist
In this lesson, we'll learn how to add the ability to toggle whether a user has a movie within their watchlist. We'll also query and display whether a movie is in the authenticated user's watchlist as well.
- Author
- Tom Gobich
- Published
- May 10
- Duration
- 9m 56s
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
Toggling A Movie in an Authenticated User's Watchlist
-
(upbeat music)
-
So now that we have our watch list defined
-
inside of our database,
-
let's go ahead and make use of it by adding a button
-
within our movie card that allows a user
-
to add a movie to their watch list.
-
So let's go ahead and hide our browser back away.
-
We can hide our database directory there.
-
And let's first go ahead and just jump into our controllers
-
and we should now have a watch list controller right here.
-
Let's grab our HTTP context import
-
and actually come to think of it,
-
we should have created this controller here as a resource.
-
So let's go ahead and just delete it out temporarily,
-
move that to our trash, jump back into our terminal,
-
stop our server, clear that out,
-
node, ace, make, controller, watch list.
-
And we could do hyphen R or hyphen hyphen resource
-
to add in resourceful methods,
-
which would be index, create, update, delete,
-
so on and so forth.
-
But really for this, all that we want is an index
-
for when it comes time to list out the watch list page,
-
a toggle method to allow the user to toggle
-
between having the movie in their watch list
-
and not having it in their watch list.
-
And then we're also gonna want another toggle
-
specifically for just whether or not the movie was watched.
-
Okay, let's go ahead and boot our server back up,
-
npm run dev, hide that away, jump into our new controller,
-
and there we go.
-
So right now our main target is to allow a user to toggle
-
whether or not a movie is inside of their watch list.
-
So what we're gonna want is our response
-
so that we can redirect user back
-
after they perform some action,
-
our params so that we can get the IDs applicable
-
as well as auth so that we can get the user applicable too.
-
So from our params, we're gonna want to be able to get
-
the movie ID and then we're also going to want our user ID
-
from our auth user.id there.
-
And right after our user,
-
we're gonna put an exclamation point
-
because we're gonna use the middleware to ensure
-
that in order for us to reach this method,
-
the user is actually authenticated.
-
And that will just essentially remove
-
the undefined portion from the type.
-
Then we'll wanna check and see whether or not
-
a watch list for that user in this movie already exists.
-
So we do watch list equals await auth.user,
-
we'll add another exclamation point to assert
-
that we do have a user and then do related watch list.
-
And we'll query where we have the movie ID
-
and we only care about the first.
-
So we'll just grab the first there.
-
So there's plenty of ways that you can actually query that.
-
That's one way.
-
You could of course also just do it directly
-
from the watch list model.
-
So for example, we could do await watch list,
-
import that from our model, query where,
-
and then check for both the movie ID
-
as well as the user ID there and grab the first.
-
Whatever your preference is.
-
This one here is probably actually a little bit cleaner.
-
So we'll go ahead and cut that out
-
and paste it in and use this one.
-
Okay, so let's scroll down a little bit.
-
If we have a watch list, so if watch list actually exists,
-
then what we wanna do is just delete it.
-
So we'll await watch list delete.
-
Otherwise, if it doesn't exist,
-
then we just wanna create it.
-
So we can await watch list dot create
-
and pass in our movie ID as well as our user ID there.
-
Once we've done that, we can go ahead and return response,
-
redirect the user right back to where they were.
-
Okay, let's give that a save.
-
Now let's jump into our routes
-
and let's go ahead and put this after our movies.
-
So do router dot, and this will be a post slash,
-
watch lists slash, and we only need the movie ID
-
that we wanna toggle.
-
And then we'll do another slash
-
and specify that we specifically
-
just want this route to be for toggling.
-
Import our watch lists controller,
-
scroll down to there, hit tab to auto import that
-
and pass this our toggle handler as watch lists toggle.
-
All right, give that a save.
-
Then let's go ahead and scroll down to our components,
-
go into our movie card and down to our button.
-
Let's just go ahead and give this button here a copy
-
and we'll put this action above it,
-
but we only wanna show this button if we have an off user.
-
So we'll go ahead and end our if there
-
and paste our button in.
-
For right now, we don't have a way to actually tell
-
whether or not the user has this movie in their watch list.
-
So we'll just do a strict add to watch list button
-
and we'll make that conditional here in a little bit.
-
For our href, we no longer want that to be a route
-
and we probably don't want the class margin top on that
-
either, we'll remove it from our button below
-
and wrap this whole section here in a div
-
with that applied here momentarily.
-
But we do want this button to have a type of submit
-
and we also want to wrap this button in a form method,
-
post action will be route watch lists dot toggle.
-
And we need to specify the movie ID as the param,
-
which is our movie dot ID.
-
And the form add in our CSRF field,
-
give our button an indent and end the form.
-
All right, let's go ahead and pause here,
-
give that a save, hide our text editor back away,
-
jump into our browser and whoops, I did watch lists.
-
Jump back into my text editor here
-
and let me add the L right there.
-
Okay, back into the browser, give that a refresh.
-
There we go.
-
All right, so yeah, we do need to fix the margin there,
-
but if we right click somewhere, inspect,
-
let's jump into our network tab, go into XHR,
-
click the gear, persist our log
-
and let's go ahead and click on add to watch list.
-
Oop, right, that's not an XHR, that's a form.
-
So let's go back to all and we can see
-
that it did a post request out to our slash toggle.
-
If we hover over that toggle,
-
we can see the full URL is watch list slash 420 slash toggle
-
and then that redirected us with a 302
-
right back to where we were, which is our homepage.
-
So that does seem to be working.
-
Let's go ahead and hide this back away
-
and give ourselves a way to determine
-
whether or not this movie is in the user's watch list.
-
So let's jump back into our text editor
-
and we're gonna wanna find all of the methods
-
where we're using movie card.
-
So I'm gonna hold command shift F to open up find.
-
It'll be a little search icon right around over here
-
if you have that toolbar enabled
-
and we'll do a search for at exclamation point movie.card
-
and it looks like we have this on,
-
expand this out here momentarily,
-
our resources views homepage,
-
our director's show page,
-
our movies index page and our writer's show page.
-
So first let's go ahead and jump into our home controller
-
and we'll take care of that one first.
-
And this is just gonna be a conditional preload
-
based off of whether or not we have an authenticated user.
-
So if auth user, if we have an authenticated user,
-
then we'll want to apply to our query,
-
query.preload our watch list.
-
I'm gonna go ahead and break this down
-
so that it's a little easier to follow
-
because inside of our preload watch list,
-
we're also going to have another query
-
where we want to limit the watch lists that are preloaded
-
to just those where the user ID
-
is our auth user exclamation point.id.
-
So if we have a user at all,
-
then we want to add to our entire movie query
-
a preload for our watch list
-
and then specifically to our watch list preload,
-
we want to limit those just where the user ID
-
is the currently authenticated user.
-
This should only ever be one
-
and we can actually enforce that
-
at the database level here momentarily too,
-
but we'll go ahead and leave it as a list
-
because that's what the relationship here will be expecting.
-
So we'll give that a save, it'll do its formatting.
-
I think it's complaining there
-
because we already used query.
-
Yep, so I'll just call that maybe watch list
-
since it's the watch list specific query.
-
There we go.
-
And now we just want to give this section here a copy.
-
We also need to apply it to our recently released here too.
-
So we can paste it there,
-
go into our director's controller down in the show method.
-
We're gonna want to break this query down a little bit
-
and paste our if inside of there.
-
It's like we also need to grab auth out of the HTTP context,
-
give that a save.
-
There we go.
-
This is our movies controller.
-
All right, this one should just be the index method
-
and it looks like we're using our get filtered there.
-
So let's go ahead and dive into there
-
by command clicking into it.
-
And at the end of our if chain here,
-
let's just go ahead and paste one more in.
-
And now we need to make our auth user accessible
-
within here.
-
We can either pass that in as a parameter,
-
which would be the most straightforward way,
-
or we can inject our HTTP context into the service.
-
Since we have this as a static method,
-
we'll go ahead and add it as a parameter for right now.
-
So at the end of our parameter list,
-
we'll add in user of type user and import that from a model
-
or have that be undefined and default it to undefined.
-
Give that a save so that it can do its formatting.
-
And then we just need to switch this to if user
-
and where user.
-
Okay, and then lastly, we have our writers controller
-
and it should be the show method right there.
-
So we'll give it one more paste
-
and grab auth out of the HTTP context there as well.
-
Nope, we did this one here a little bit different.
-
If won't be here,
-
but rather it will be within the movies written preload.
-
So we want to do query there, query,
-
break that down and paste it in there like so.
-
Give it a safe set of formats
-
and we'll go ahead and switch this one to written
-
since it is specifically for our written movies.
-
All right, so now we should have our watch list preloaded
-
everywhere that we're using our movie card.
-
So now within our movie card,
-
we should be able to tell whether or not the movie
-
is in their watch list by checking to see whether or not
-
watch list has a length.
-
So we can cut that out, do double curly braces
-
and check whether movie.watchlist has a length.
-
If it does, then we'll say maybe in your watch list,
-
otherwise we'll paste in our add to watch list text.
-
Give that a save.
-
And now if we jump into our browser
-
with our coming soon section,
-
we can now see in your watch list here for our button.
-
If we give that another click,
-
it's now back to add to watch list
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!