
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
Complete source code for this lesson is available at
How did you manage to remove the blur property and reach here?
Upgrading gives you access to quizzes so you can test your knowledge, track progress, and improve your skills.
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:02 Today, we'll be working on the profile page.
00:00:05 It has quite a lot of details.
00:00:08 And finally, we'll be able to learn a bit more about the users that use our application.
00:00:12 So back in our editor, let's head over to our actions, this time to our user.action.ts file.
00:00:20 where I will collapse all of the current functions we have right now.
00:00:24 And instead of getting all the users, now we just want to fetch the details of a single user.
00:00:29 Now keep in mind that this page has to be public as we want to be able to see everyone's profiles.
00:00:34 So we'll have to pass the user ID to our server action instead of getting the currently logged in user from our action malware.
00:00:41 So first things first, let's head over into the action.d.ts file where we can define the props I'll call it interface get user params.
00:00:53 And we simply want to accept a user ID of a type string.
00:00:58 We're going to also head over into validations.ts and at the bottom of that file, I'll export const a new get user schema,
00:01:10 which will be equal to z.object.
00:01:13 where we'll have a user ID of a type string min1 character.
00:01:18 And then we can create that server action that allow us to fetch the user.
00:01:23 So let's follow the structure we have right here.
00:01:26 Export async function getUser.
00:01:29 It'll accept params of a type getUser params and it'll return a promise.
00:01:38 That'll contain the action response and specifically in this action response, we will return an object where user will be equal to the user interface.
00:01:49 We'll also return the number of total questions for that user, which will be equal to a number.
00:01:56 And we'll also return a number of total answers provided by that user, which will be a number.
00:02:02 Make sure to import this user from the database.
00:02:04 So right here at the top, and then we can close this right here and open up a function block.
00:02:10 Now within it, we can first call our action by saying const validation result is equal to await action to which we need to pass over the params.
00:02:24 as well as the schema equal to getUserSchema coming from validations.
00:02:30 You know the drill, if we have the validation result and if it has an error, just return it.
00:02:35 Else, we can destructure the user ID coming from programs.
00:02:41 Then let's open up a try and catch block.
00:02:44 In the catch, we can simply return the handle error as error response.
00:02:49 And in the try, let's go ahead and fetch the user by saying const user is equal to await user.findById to which we're going to pass the user ID.
00:03:03 If there is no user, we can simply throw a new error, user not found.
00:03:09 But if we do have a user, we can fetch the number of total questions by saying const totalQuestions is equal to await questionModel.countDocuments where
00:03:21 the author property matches the user ID of the user we're trying to fetch the details for.
00:03:28 And we can do the same thing for the total answers by using the answers model.
00:03:35 So I'll say answer.countDocuments where the author is the user ID we're trying to get the details for.
00:03:42 Finally, we can return an object where success is true and pass over the data of JSON parse, JSON stringify user, as well as the total questions and total answers.
00:03:55 You see that we are following the same structure we have followed up to this point.
00:03:59 So when I'm writing something, Copilot automatically suggests improvements.
00:04:03 and I know it might seem like I'm going through this fast, but I'm just using my natural pace.
00:04:10 It's just that as this project evolves, we already put structures in place that allow us to just do it without thinking because we know how the structure
00:04:18 looks like.
00:04:19 And thankfully, Copilot follows that and just gives me what I want.
00:04:22 Right here, we have one warning saying that user refers to a value, but it's being used as a type, so you just want to add a type of user right here.
00:04:31 And with that, we have a server action that allow us to fetch the user details.
00:04:36 So let's go ahead and commit it by saying something like implement getUserServerAction, commit it and sync it.
00:04:46 And in the next lesson, we can start implementing the profile page.