Making A Reusable Movie Card Component
In this lesson, we'll learn how we can make a movie card component with EdgeJS that we can define once and easily use throughout our markup.
- Author
- Tom Gobich
- Published
- Feb 10
- Duration
- 10m 24s
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
Making A Reusable Movie Card Component
-
(upbeat music)
-
So EdgeJS also has the concept of components.
-
Now, unlike Vue or React or anything like that,
-
where it's front-end based,
-
these are server-side components,
-
so they don't have reactivity baked into them.
-
They're used to define reusable markup
-
within our template system.
-
Components also have their own isolated state as well.
-
So if you share something from your route handler
-
into your Vue, your component won't know about it
-
unless you explicitly pass that variable
-
from your Vue to your component.
-
So we have our three movies, right?
-
Right now, they're just in a list,
-
but let's go ahead and create a card component for them,
-
and we'll use the Pines UI card here to do so.
-
So if we go into the code here,
-
we'll see it's just some markup using TailwindCSS.
-
So we can go ahead and give this a copy
-
just to give us a quick jumpstart
-
on what exactly we are doing here.
-
Let's go ahead and hide our browser back away.
-
Within our Vues, let's go ahead and right-click it,
-
and let's do New File.
-
We'll create a new folder called Components.
-
This is where all of our components will live within EdgeJS.
-
And then let's go and create a new folder
-
within here called Movie,
-
and then within Movie, we'll create a card.edge file.
-
The full tree of that is now Components, Movie, card.edge.
-
We can paste the contents that we copied
-
from Pines UI directly into here.
-
And to match the slate coloring
-
that we've been doing so far,
-
I'm just going to go ahead
-
and find a replace neutral with slate.
-
So let's go ahead and dive back into our homepage,
-
and let's attempt to use this.
-
So we don't need any of the extra stuff
-
that we've added in here for our list item.
-
Currently, so let's just go ahead
-
and get this all back down to just a simple list.
-
Above our unordered list,
-
let's go ahead and create a new element.
-
We'll put these within a div for right now.
-
Let's call this class.
-
We can flex, allow them to wrap,
-
and we'll give them a gap of three.
-
There's a couple of different ways
-
that we can make use of our new card component.
-
We can use the component tag, so component,
-
and then provide the path to the component.
-
So that would be components, movie, and then card.
-
Let's go ahead and give this a save
-
and see exactly what we're looking at.
-
So let's dive back into our browser,
-
and sure enough, there is the card right above our list.
-
All right, so let's go ahead and hide our browser back away.
-
So we have our card.
-
Now we need to figure out how to provide movie information
-
into our card.
-
Well, the second argument is how we can pass props
-
directly into the component
-
so that they will be accessible
-
via the state of the component,
-
enabling us to use it the same way
-
that we are here within our page.
-
So this particular component's really only in charge
-
of rendering out one movie.
-
So what we'll wanna do is reapply our loop.
-
So let's go and copy our each, paste it above our component,
-
and then we'll end it after our component.
-
We won't need the index,
-
so we'll go ahead and get rid of that.
-
Okay, next, let's go ahead and just provide our movie
-
into the props of our component.
-
We can give this a save, and we can jump back into our card.
-
Within our H2, we can go ahead and hit Enter
-
to break that down into a new line,
-
and we can use interpolation, so double curly braces,
-
to attempt to reach for our movie title.
-
We can do the same thing for our paragraph.
-
We can go ahead and hit Enter to break that into a new line,
-
and we can apply our movie summary.
-
Lastly, we have our button.
-
For us, we don't actually want this to be a button,
-
but rather an anchor, so we'll change that to an A,
-
and then we'll do href,
-
and then we'll link to our movie detail page.
-
So that's route, movies.show,
-
and then we'll wanna provide the slug of movie slug.
-
We're gonna wanna jump to the end of the file
-
and replace the end tag to an A as well,
-
and we're not going to be viewing a product,
-
but rather view movie.
-
Okay, cool.
-
So now we've passed a movie into the props
-
of this component, and we're making use
-
of all of the different properties on our movie
-
to populate the different details of the card itself.
-
So at this point, if we go ahead
-
and dive back into our browser,
-
we should see three of these cards.
-
They're in a list at the moment, but we will fix that,
-
and if we take a look at the title,
-
we'll see My Awesome Movie, Awesome Movie, The Trilogy,
-
and Another Awesome Movie.
-
So we're getting one for each movie that we have.
-
Additionally, if we go ahead
-
and hover over the View Movie button,
-
we'll see down in the bottom left-hand corner
-
that it is attempting to go into the movie detail page
-
for each one of the different movies that we have.
-
We can go ahead and click on one, and sure enough, it works.
-
So let's go ahead and put these into a grid.
-
So let's hide our browser back away,
-
and we'll wanna go back out to our homepage.
-
And so if we take a look at our top-level div here,
-
and we scroll over through the class list,
-
we'll see that it has a width of 380 pixels.
-
Well, at this point in time, we don't really know
-
what width we want it to be, because we're not quite sure
-
how many movies we're gonna wanna squeeze
-
onto a single row.
-
It would be nice to be able to specify that at this level,
-
where we're actually using the movie component,
-
because we could be using it in a grid
-
that has plenty of room, or we could be using it
-
within an aside that's limited to just 300 pixels.
-
That's where that ATTRS helper that we took a look at
-
on the HTTP variable in the last lesson comes into play.
-
So if we dive back into here,
-
let's give our class list here a copy.
-
We can use keyboard shortcuts here
-
to just select all of our class lists.
-
So I'm gonna Command + Shift, and then hit the right arrow,
-
and it's gonna jump us to the end of the line
-
and select everything in between.
-
And then we can let go of Command,
-
so that we're just holding Shift,
-
and hit the left arrow two times.
-
Command + X to cut it, and there we go.
-
Now we can get rid of our class altogether.
-
So now let's go ahead and do double curly braces,
-
and then HTML, ATTRS, and let's break this down,
-
so that it'll be a little bit easier to work with.
-
We'll do an array, we'll add in an object,
-
and define our class.
-
We'll have our class be an array.
-
We'll start it with a string,
-
and then we'll just go ahead and paste everything
-
that we had cut into here.
-
Lastly, let's also get rid of the specific width designation.
-
Cool, so at this point, we are actually specifying
-
the exact same thing that we had started with.
-
So at this point, we're not actually able
-
to define anything outside of our cards on our homepage,
-
where we're actually using the component,
-
specifying what we want the width to be.
-
Because within our card component,
-
we're not making use of anything
-
that would allow us to change this at our homepage level.
-
We'll want to reach for something like we are
-
with our movie details,
-
to enable us to add classes into our class array.
-
What we would like to do is be able to just use class,
-
but that's a reserved word within JavaScript.
-
So we're gonna get an error if we just attempt to do that.
-
However, we can reach for a property
-
called $props, to read directly from a props object,
-
where we can then use class
-
to add any additional classes into our class array.
-
So now if we give this a save,
-
jump back to our homepage,
-
within the props of our component,
-
we can now add in an additional item called class
-
and add in width one third.
-
If we give this a save, jump back into our browser,
-
that's a little bit better.
-
The gap that we applied onto our grid
-
is kind of messing that up a little bit.
-
So let's go ahead and get rid of that gap
-
and see if that fixes our row.
-
Sure enough, there we go.
-
So now the one third width is being applied
-
to each one of our different cards within here,
-
but we're not done yet.
-
So let's go ahead and hide our browser back away,
-
jump back into our card component.
-
This props variable can actually directly digest
-
into attributes itself.
-
So once more, let's go ahead and copy the class list
-
that we have right here.
-
And let's get rid of everything that we have so far
-
within our outer double curly braces.
-
So we can reach directly for props
-
and this property itself actually has the capability
-
to say, all right, let's digest these props to ATTRS.
-
Now, when we save this and we jump into our browser,
-
we're gonna see a little bit of an adjustment
-
that we need to make,
-
but for the most part, things still look right.
-
Let's go ahead and right click though,
-
and we'll see where the issue is coming into play.
-
So if we scroll down a little bit
-
and we take a look at the outermost div for these cards,
-
you'll see that we get our class of width one third,
-
which is being applied via our props,
-
but we're also getting our movie object added in
-
as an attribute, which we don't want one bit.
-
Additionally, we haven't added in
-
our other classes yet either.
-
So what we can do is if we hide that back away
-
and minimize our browser once more,
-
is we can tell props that we want to switch everything
-
to attributes except and provide this in an array
-
and provide that the movie to specify
-
that we want to change all of our props
-
except our movie array to ATTRS
-
or attributes for this particular div.
-
So this is gonna fix the issue
-
where we're dropping our movie directly
-
into the divs attributes here,
-
but we still need to add in the classes that we have copied.
-
So let's also add class to this except list as well.
-
And let's add that in ourselves.
-
So I'm gonna go ahead and collapse this down
-
to a single line here,
-
and I'll give it a single line break here.
-
And above this, we can specify our class,
-
do double curly braces within here.
-
And now I can do our HTML class name designation
-
and in our array, paste in the string that we have copied.
-
And then at the end of here,
-
we can reach directly for props.class and merge that in.
-
Now, if for any reason we wanted props.class to be optional,
-
we could absolutely do that.
-
Just wrap it in parentheses and default it to an empty string
-
so that it doesn't end up plopping undefined
-
within our class list.
-
Okay, cool.
-
So let's give this a save and see what we have now.
-
So if we dive back into our browser,
-
I got a typo.
-
That should be class names, not class name.
-
Let me go fix that real quick.
-
So class names, give that a save, give this a refresh.
-
There we go.
-
So now each of our cards has its class applied.
-
And if we right click on this, inspect,
-
take a look at the outermost div
-
where we have our width of one third defined.
-
You'll see that we no longer have our movie
-
trying to be plopped on as an attribute within this div.
-
Cool.
-
So we can hide that back away.
-
And let's give our movies a little bit of spacing here.
-
So let's go ahead and hide this away,
-
jump back out to our homepage.
-
And with our flex, we can do negative MX six.
-
And then within our class where we're doing
-
our width one third, we can add PX three.
-
And since the outermost div within our component itself
-
has bordering and all of that fun styling on it,
-
we actually don't want to apply the padding
-
directly on this component.
-
Instead, we'll wrap it inside of another div
-
so that we can apply the padding here instead.
-
So we'll do PX three.
-
And now this is the class we'll want width full,
-
LG width one third applied to,
-
and instead of width one third here,
-
we'll now want width full.
-
We can give this a save, jump back into our browser,
-
and there we go.
-
So now they have a little bit of spacing
-
between one another.
-
Lastly, we can use lorem pixum to switch these images out
-
so that we're not seeing the same image
-
over and over again.
-
All that we need to do is copy this URL right here.
-
It's just pixum.photos/ whatever size you need.
-
Let's hide our browser back away,
-
dive back into our card component,
-
and let's replace the source for this particular image.
-
Go ahead and paste in what we've copied.
-
And instead of 200, maybe we'll do 450
-
just for safety sake to give us enough pixels.
-
While we're here, I'm also gonna go ahead
-
and fix up the intenting.
-
Looks like Pine's UI uses four spaces
-
whereas I like to use two.
-
Okay, there we go.
-
Got the intenting fixed up there.
-
Let's go ahead and give that a save,
-
jump back into our browser.
-
And it looks like we're getting back the same image
-
for all three regardless.
-
If we refresh the page just to make sure.
-
Yeah, sure enough.
-
All right, so let's hide our browser back away.
-
Let's also add in a height.
-
So those were a little tall for my liking,
-
so let's switch them to 200 pixels tall.
-
And let's see if maybe we can add in a V equals
-
and inject our movie slug onto the end of that
-
to get us back a different image per movie.
-
So let's give that a save, jump back into our browser.
-
And there we go.
-
So now we're getting back a different image
-
per movie that we have.
-
We can go ahead and get rid of our plain list movies
-
down here.
-
So we'll hide our browser back away,
-
head back into our homepage,
-
and now we can get rid of our UL altogether,
-
just like so.
-
And now we're ready to move onward.
-
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
-
The Flow of Middleware7m 49s
-
Authenticating A Newly Registered User4m 14s
-
Checking For and Populating an Authenticated User2m 10s
-
Logging Out An Authenticated User2m 24s
-
Logging In An Existing User6m 54s
-
Remembering A User's Authenticated Session6m 55s
-
Protecting Routes with Auth, Guest, and Admin Middleware5m 36s
-
-
Filtering and Paginating Queries
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!