🕰️ Chapters
- Adding Profiles Show Route
- Defining Profiles Show Route Handler
- Creating Profiles Show Page
- Adding @handle Profile Route
- Adding @handle Route Handler
Displaying A User's Profile
In this lesson, we'll learn how you can mimic popular sites and use an @ handle to display your user's profiles
- Author
- Tom Gobich
- Published
- Jun 01
- Duration
- 6m 1s
![Tom Gobich](/img/1/profile/avatar_1703713552864.jpg)
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
Displaying A User's Profile
-
(upbeat music)
-
Now that our users are able to edit their profile,
-
let's go ahead and add in an actual profile show page
-
into our application.
-
So let's hide our browser away,
-
and let's go ahead and scroll on down
-
to where we have our profile routes defined right here.
-
All right, let's do router.get/profiles/
-
this is where it'd be really nice
-
to have something like a username,
-
but we don't have that within our application,
-
so we're just gonna do ID here,
-
reach for our profiles controller,
-
and we're gonna add a show method here,
-
as profiles show.
-
All right, and give that a save.
-
Let's go jump into our profiles controller,
-
scroll on up a little bit,
-
and let's add in an async show method.
-
We'll take our view and params,
-
HTTP context,
-
and since we're searching by the ID,
-
we can do const user equals await user,
-
reach for our user model,
-
and just do find or fail,
-
providing in our params.id from our route parameters.
-
Then we can await user load their profile in.
-
So now we'll be able to access the user's profile
-
via user.profile,
-
and we can return view render,
-
and let's do pages profiles show,
-
and provide that user in.
-
All right, now we need to go create that page,
-
so let's scroll on down,
-
and we actually have a pretty good starting point here
-
from our directors or writers show page.
-
So I'm gonna go ahead and just copy this.
-
We can paste it directly inside of our profiles directory,
-
just like so.
-
Scroll on up,
-
and then we can replace our director line here
-
with instead just user,
-
and then we currently don't have movies,
-
so I'm just gonna go ahead and comment this out.
-
That's gonna be our next step,
-
and now we should be able to jump back into our browser,
-
and actually I'm not entirely sure what this user's ID is.
-
So I'm gonna go into edit here,
-
and just quickly inspect auth user ID
-
to see what exactly that is.
-
Type of inspect, there we go.
-
Refresh that.
-
All right, looks like it's seven.
-
So jump back in here and get rid of that.
-
Okay, so we should be able to go to profiles/7
-
to view this user's profile.
-
We hit enter here.
-
There we go.
-
We can see we get John Doe edit three,
-
which matches our authenticated user.
-
Let's go ahead and add in their additional details.
-
Let's jump back into that show page.
-
We'll do a little div class flex,
-
items center gap, maybe four.
-
We'll do div class width, maybe 52, I think, for the image.
-
And then we'll do image class width full,
-
source equals user.avatarURL.
-
Remember, we're showing a specific profile here,
-
so we don't wanna reach for auth user,
-
but rather the user that we're providing
-
into this page state, and an image out.
-
Also wanna add an alt user.
-
Let's wrap that in an if user avatar URL, just like so,
-
and end that up.
-
In addition to that, let's go ahead and do a div
-
and paste that h1 back in,
-
as well as a p tag with the user profile.
-
And I think we called it description,
-
so we'll add that in there too.
-
Give that a save, and let's see what we get real quick.
-
All right, 52 might be a little bit too big there.
-
I think 16 there is the winner.
-
Let's also remove the margin bottom
-
on both of these here as well.
-
All right, jump back into here.
-
Margin, actually get rid of the margin y on the h1.
-
So it's gonna have some on the top too.
-
All right, let's see how that looks.
-
Cool, that looks okay.
-
Let's go ahead and give the entire block here.
-
Maybe we'll do p top eight,
-
adding bottom, maybe 12, and all right, cool.
-
So we have a good starting point here for our profile page.
-
Now, one thing that you see a lot of applications do
-
is they have this like at,
-
and then the username system going on.
-
So let's go ahead and show how we can do that.
-
We don't have usernames,
-
but we can at least work with our ID here
-
to show how you would go about it.
-
So let's hide our browser back away.
-
We need to jump back into our routes.
-
We'll go ahead and leave this route here as is,
-
as that's what we're gonna be using at the end of the day,
-
but let's go ahead and scroll up with that copy
-
and paste it in here.
-
Okay, we'll wanna get rid of the slash profiles
-
and we'll just do ID here.
-
And I'm gonna get rid of the name
-
just so that we don't get a duplicate name error.
-
Typically you would call this something like username
-
as that's what we would actually be passing in.
-
But since this is pretty dynamic,
-
it's actually gonna match for any route that we have
-
as just slash at present.
-
So if we were to save this
-
and try to go into slash movies,
-
it's gonna end up trying to match against our slash username.
-
So let's give that a save real quick,
-
jump back into our application
-
and attempt to go into slash movies.
-
And you'll see that it tried to go
-
into our profiles controller show method
-
and it failed on the find or fail
-
because it can't find anything for an actual ID of movies.
-
So how do we remedy that?
-
Well, we can use a route parameter validator using where
-
to limit the user name route parameter
-
and we can use a matcher.
-
Now there's not gonna be a router.matchers applicable
-
to verifying that something starts with some prefix,
-
but we can use regex.
-
So we can do slash caret to verify starts with,
-
and we wanna verify that it starts with an at character.
-
So with that applied,
-
in order for this route to match the URL,
-
our username needs to start with an at character,
-
meaning that if we give this a save,
-
jump back into our browser
-
and try to refresh our movies page, it's back to working.
-
But if we just try to go into at seven now,
-
which remember we're using our ID
-
in place of an actual username,
-
since we don't have usernames inside of this application,
-
hit enter there, we're gonna need to find or fail
-
because now it's trying to search for at seven
-
and our route parameter itself is called username now.
-
So let's take care of that too.
-
So let's jump back into our profiles controller
-
and let's actually copy this
-
rather than trying to merge everything into one.
-
And we'll call this maybe just at,
-
since it's prefixed with the at character.
-
Our program is now username
-
and in order for at to be used and matched as a route,
-
it's going to need to be prefixed with an at character.
-
So what we can do is get our ID back
-
by doing const ID equals params username,
-
replace the at character with just an empty string.
-
And then this is no longer params ID, but just ID like so.
-
So in order to match the route,
-
we need to start with an at character
-
and then we just need to remove that at character
-
to get our ID back, to be able to search and find the user.
-
You would do that exact same flow
-
if you were working with an actual username too.
-
Okay, jump back into our routes
-
because we need to switch from show to at,
-
give that a save, just jump back into our browser
-
and let's try our at seven once more.
-
And look at that, it's back to working, so cool.
-
There's an alternative approach
-
if you're looking for something
-
a little bit shorter for your URL,
-
and this at premise is pretty popular across the internet.
-
So that's how you can go about it here with AdonisJS.
-
Introduction
-
Fundamentals
-
2.0Routes and How To Create Them5m 24s
-
2.1Rendering a View for a Route6m 30s
-
2.2Linking Between Routes7m 52s
-
2.3Loading A Movie Using Route Parameters9m 18s
-
2.4Validating Route Parameters6m 7s
-
2.5Vite and Our Assets6m 39s
-
2.6Setting Up Tailwind CSS7m 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 8s
-
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
-
8.5Validating Query String Filter Values7m 24s
-
8.6How To Paginate Filtered Query Results9m 15s
-
8.7Pagination First, Last, Next, and Previous Buttons4m 3s
-
-
User Watchlist
-
9.0An Alternative Approach to Many-To-Many Relationships4m 56s
-
9.1Toggling A Movie in an Authenticated User's Watchlist9m 56s
-
9.2Listing and Filtering User Watchlist Items7m 31s
-
9.3Allowing Users To Toggle A Movie As Watched4m 44s
-
9.4Filtering By User's Watched Status6m 7s
-
9.5Defining A Composite Unique Constraint4m 47s
-
9.6Persist Filters Easily with Lucid's Query String Method3m 58s
-
-
User Profiles
-
10.0How to Create and Fix Missing User Profiles in Your Application7m 37s
-
10.1Using Dependency Injection to Update A User's Profile9m 46s
-
10.2Saving All Or Nothing with Database Transactions5m 15s
-
10.3Uploading and Displaying User Avatars15m 29s
-
10.4Displaying A User's Profile6m 1s
-
10.5Filtering, Preloading, and Sorting By Relationship7m 6s
-
-
Admin Panel
-
11.0Creating An Admin Layout7m 14s
-
11.1Counting Stats for our Admin Dashboard5m 43s
-
11.2Paginated Admin Movie Table13m 2s
-
11.3Allowing Admins to Create Movies16m 39s
-
11.4Allowing Admins to Update Movies and Clear Values13m 27s
-
11.5How To Use One Form to Create or Edit Movies5m 32s
-
Uploading Movie Cover Images in our Create or Edit Form10m 29s
-
Using A Wildcard Route Param to Download Storage Images7m 57s
-
Posting Objects, Arrays, and an Array of Objects in HTML Forms26m 26s
-
Managed Transactions and Syncing Movie Cast Members15m 55s
-
Allowing Admins to Delete Movies and their Relationships7m 42s
-
Thank You for Watching!0m 31s
-
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!