
No Comments Yet
Be the first to share your thoughts and start the conversation.
Be the first to share your thoughts and start the conversation.
Complete source code available till this point of lesson is available at
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
00:00:02 To create the tag details page, let's go ahead and create a server action that'll fetch all questions associated with each specific tag.
00:00:10 Just before we create it, let's go ahead and create a new schema for this action by heading over to validations.ts.
00:00:18 Currently, we have the paginated search params schema, which will extend by saying export const get tag questions schema,
00:00:30 which is equal to paginated search params schema dot extend.
00:00:37 and we want to extend it with a tag ID, because on top of the page, page size, query, and more, we'll also be searching based on the tag ID.
00:00:47 So, let's say that this is a z.string of main characters 1. And let's also head over to action.d.ts And here we can create a new interface called get tag
00:01:04 questions params.
00:01:04 And it'll also extend the paginated search params, but it'll extend it by omitting the filter property from it because we don't need to filter anything.
00:01:18 as we'll only be able to search by the tag ID of a type string.
00:01:23 So here you can see how we can use some of the more complex TypeScript functionalities such as extends, where now the get tag questions params will extend
00:01:33 all of the page search params, but we can also omit a specific param such as filter and then add additional params such as tag ID on top of the ones that
00:01:43 we already extended.
00:01:44 Now, let's head over to our tag actions.
00:01:48 That's going to be the new file we created.
00:01:50 And I think I called it actions, but just to stay consistent with everything we have so far, we can also just rename it to action,
00:01:58 because it'll be an action file for the tag, similar to as how this is the action file for the question.
00:02:05 And now, let's create a new function by saying export const get tag questions and we'll make that into an async arrow function.
00:02:15 Now, there are two different approaches that we can take.
00:02:18 The first one is to make a call to the questions model and find questions that contain this tag.
00:02:24 And the second one is to make a call to the tag questions model and find all related questions together by finding different documents that have the tags
00:02:33 mentioned in them.
00:02:34 Both approaches are totally valid, but in this case, we'll go with the first option.
00:02:39 The reason behind that is that although making a call to tag questions would have been similar, as it just has two fields where we have the direct reference
00:02:47 ID of the questions, things get difficult when you have to search questions of that tag by tag title.
00:02:53 With that approach, we'll have a slightly difficult filter expressions as we don't have to just populate questions, but also have to get their title and
00:03:01 check if they match the provided query.
00:03:03 This is not as easy to understand, so that's why we're going to go with the first approach.
00:03:08 We can just call the questions model, directly apply a filter query on the questions title, in the same way we call the getQuestions in the question action
00:03:18 right here.
00:03:18 So, let's make our life easy and keep our code clean by doing just that.
00:03:23 Once again, this will be almost exactly the same as what we had in the get tags.
00:03:28 So actually, I'll go ahead and copy the entire get tags function and override this one right here.
00:03:35 But of course, I will rename it to get tag questions.
00:03:41 This time our params are going to be of a type get tag question params and in the action response we can return a tag, now a singular tag,
00:03:52 but rather we'll return a list of questions which will be of a type question array.
00:03:58 Remember that this is not a question model but rather a type we have specified in the global.d.ts file.
00:04:05 that has all the info about a question.
00:04:08 Then we try to validate the params we pass in based off of the get tag questions schema.
00:04:14 We check if there are any errors.
00:04:17 We destructure all the params, but this time we don't have access to the filter.
00:04:22 Instead, we have access to the tag ID.
00:04:24 We check if we need to skip something or limit it.
00:04:27 In this case, we can remove the sort criteria.
00:04:29 So I will remove this part right here.
00:04:32 and I will actually move the filter query and the if for the query right within the try block.
00:04:38 I'll explain soon why I did that.
00:04:40 It's because we first have to fetch the tag and make sure that nothing went wrong and then with its tag id we can do further actions.
00:04:47 For example, I can say const tag is equal to await tag dot find by ID, and then I can pass in the tag ID.
00:05:00 Next, we can do some error handling by saying, if there is no tag, then simply throw a new error, tag not found.
00:05:08 And then we can start building out the query filter for questions to see if tag ID exists in the tags array.
00:05:15 We can do that by saying const filter query of a type of question.
00:05:20 And then here we can say, tags, whether it includes, so dollar sign in, the array of tag ID.
00:05:31 And this question has to be imported from add forward slash database.
00:05:34 So we're filtering only the questions that have that specific tag within their tags array.
00:05:39 Then we can check the query.
00:05:41 in case we want to search for some additional questions within that tag.
00:05:45 This will remain the same, but this time we don't have to do the or.
00:05:48 I'll simply check for the filter query dot title and then we don't have to specify the name here.
00:05:53 We can simply say regular expression where we pass the query with the options of i.
00:05:59 Finally, we want to fetch the total number of questions.
00:06:02 So that'll be total questions is equal to tag documents based off of the filter query but we count questions not tags because this function even though
00:06:13 it is about tags it is actually about fetching questions for that tag after that we want to fetch all the questions that match by saying const questions
00:06:22 is a weight questions.find filter query.
00:06:26 We want to remove the sort criteria.
00:06:28 This is actually question.find and we want to select some information out of each one of these questions.
00:06:35 We don't want to get all the information back.
00:06:37 We only want to get some things like an underscore ID, title, views, answers, upvotes, downvotes, author, as well as create a dad.
00:06:49 we only want to fetch things for each question that we can display on the list.
00:06:54 Then, we also want to populate some things, such as a path of author, and then for the author, we want to select the name and the image.
00:07:04 Again, same things as before, we're selecting what we want to get so we can showcase it on the Tag Details page.
00:07:12 You know how we have that little author name and author avatar of the person that created that question?
00:07:18 Well, this is where we get it.
00:07:19 And in the same way, we have to get the name of the tag this question belongs to.
00:07:23 We skip the number of elements to get to the second page or third one, and then we provide a limit as well.
00:07:29 We check for the isNext by referencing the total number of questions and the questions.length.
00:07:36 And finally, we return success true.
00:07:38 Data will actually be a tag.
00:07:43 and also the list of questions that match that tag.
00:07:47 So JSON parse, JSON stringify questions.
00:07:50 And this is the function that should return the questions that match to a specific tag while allowing us to further query them or filter them.
00:08:01 Great.
00:08:02 Let's go ahead and push that by saying something like implement a tags question action, commit it, sync it, and now we are ready to put it to the test
00:08:13 in the next lesson.