
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 We're finally here.
00:00:04 At the start of this module, I'll told you that we'll implement this collections page.
00:00:08 And now we have done all the prep work needed to make it work.
00:00:12 So let's head over into app, root, collection, page.dsx.
00:00:19 So far, it has been completely empty, but now we can actually navigate over to it and you'll see collections.
00:00:26 So let's go ahead and implement it.
00:00:29 It'll be very similar to the all questions page.
00:00:33 Rather, that is currently our homepage where we're fetching all the questions.
00:00:38 That'll look something like this, root page.
00:00:42 And take a look, this is actually not that long of a page.
00:00:46 because everything is completely reusable.
00:00:49 Everything from pagination, querying, filtering, to fetching questions, displaying them, and then having separate components for search,
00:00:59 filtering, and most importantly, the data renderer.
00:01:03 So I'll copy this entire file and I'll override the collections.
00:01:08 So now if I switch over to collections, you'll see that it'll look the same as the homepage.
00:01:14 But of course I'll rename it to collections and I'll rename the component itself.
00:01:19 So let's see what actually is different.
00:01:23 We are destructuring all the same things from params.
00:01:27 This time, instead of calling the getQuestionsServerAction, we'll call the getSavedQuestionsServerAction.
00:01:34 But check this out, we're still passing the same things into it.
00:01:37 Pretty cool, right?
00:01:38 And instead of fetching the questions, we'll fetch the collection of the saved questions.
00:01:44 After that, we can change this from all questions to saved questions.
00:01:48 We can remove this button.
00:01:50 We also have some filters, which for now I will remove.
00:01:53 And then we have our glorious data renderer component to which you only need to pass the correct data and it does the rest.
00:02:00 So I'll pass in the collection as the data and I will map over that collection and get each saved question.
00:02:09 So collection.map, we get each individual, let's call it an item.
00:02:15 So we can pass the item.underscoreID as well as question will be equal to item.question.
00:02:23 If I save it, you'll see that it'll say no saved questions yet.
00:02:28 So let's quickly head over to our homepage, go into the data renderer component, and see whether we have saved it.
00:02:36 I'll unsave it.
00:02:37 I'll save it once again.
00:02:39 I'll also head over to my second question and save it.
00:02:43 And now I will switch over to the Collections page, and it still says No Questions.
00:02:51 So let's quickly head over into the Get Saved Questions action.
00:02:55 And if you take a look at here, we're using the user ID to filter out the questions.
00:03:02 So if the user ID is empty, it won't be able to find the questions that that user has saved.
00:03:08 And this is coming from the validation, which is coming only if the user is authorized.
00:03:13 So we have to add the authorize set to true, and then we can see the saved questions.
00:03:19 Great.
00:03:20 What else do we have to do here?
00:03:22 We're fetching all the questions.
00:03:24 Let's see if we can somehow modify this right here.
00:03:27 Maybe we don't even need to show this section, so I'll remove this entire outer section and just leave the H1 at the top.
00:03:34 Then, instead of a section, I can just call this a div with a class name of marching top of 11, flex, justify dash between,
00:03:44 gap of 5, On max SM devices, flex dash call.
00:03:50 And then small devices, just items dash center.
00:03:54 Here we have the local search and later on we can add something else to it as well.
00:03:59 Search is completely customizable.
00:04:02 So to it, we can route to routes.collection.
00:04:05 If we want to make it revalidate the right route, we made it super reusable.
00:04:10 The image search can still be search.
00:04:13 We can say search questions.
00:04:16 And pass a flex of one.
00:04:18 Later on, we can add the filters here too.
00:04:20 And then we have this data renderer.
00:04:23 The only thing you can notice right now is that it is saying empty question, which I guess still applies if we don't have any questions.
00:04:30 Because saved questions are, well, questions.
00:04:34 So now you can see how simple it is to create complete new pages when we have already built some of the best reusable components I've ever done in my next
00:04:44 year's career.
00:04:45 And now you have two.
00:04:47 So let's try to quickly unsave a question to see whether it'll disappear from here.
00:04:52 I'll do this and go back and just check this out.
00:04:55 It works immediately.
00:04:57 So I'll head over into my source control and say, develop collections page, commit it and sync it.
00:05:05 And let's also admire it in its full glory.
00:05:08 I mean, we've been looking at it in the mobile view.
00:05:10 We have the homepage.
00:05:11 We can go to a specific question.
00:05:14 We can save it.
00:05:15 That works as well.
00:05:17 The notifications appear at the bottom.
00:05:19 And then we can go over to our collections of saved questions.
00:05:22 And we also have the search input right here.
00:05:25 So if you go ahead and search for something like component, check this out.
00:05:32 We're searching for this component right here.
00:05:35 Or if you search for something like node, it'll show only the bottom one.
00:05:40 Very soon, we'll also add some filters right here so we can search based on different technologies or even sorting options.
00:05:47 So we can sort by most answers, least amount of answers, most recent, oldest, and so on.
00:05:53 Right now, this seemed like a lot of work just to be able to search for questions, right?
00:06:00 Because on the homepage, we can do that anyway.
00:06:02 But you'll learn how to do data aggregation.
00:06:06 And again, it's not just the search, but later on, once we add filters and sorting, it'll all come into place.
00:06:14 And you'll be proud of building this pipeline to be able to show the questions that are being fetched through a collections model and not being fetched
00:06:23 directly through the questions model.
00:06:25 I hope that makes sense.
00:06:27 In any case, great job on implementing this and more exciting stuff is coming soon.