
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:00 Now that our users can vote on the quality of questions other people ask, let's also allow them to vote on the quality of the answers that other people give.
00:00:09 As before, we'll have to head over to the global.d.ts file.
00:00:14 And to the question interface, we added the number of upvotes and downvotes.
00:00:19 Now we have to do the same thing for the answer interface.
00:00:23 So right at the bottom, I'll say upvotes is equal to a number.
00:00:29 as well as downvotes equal to a number.
00:00:31 Now that we've added those, let's head over into the answer card.tsx and let's find our hard-coded votes div.
00:00:40 And here we can do the same thing that we did in the question details.
00:00:44 So that is this one right here, where we use the suspense and the votes.
00:00:49 So we'll copy this entire div, flex justify end, suspense with the loading, and finally the votes.
00:00:57 I'll copy it and I'll paste it right here instead of the current div.
00:01:01 Of course, make sure to import the suspense, the votes, and everything else we need.
00:01:06 But now, the target type instead of the question will be an answer.
00:01:11 Thankfully, we made our votes functionality super customizable so we can pass either of those two.
00:01:18 After that, we'll have to pass the target ID, which in this case is just the underscore ID of this specific answer.
00:01:25 We already have access to it right here through props.
00:01:29 It looks like I forgot to close this div, so let me do that properly.
00:01:33 And next, we have to pass over the hasVoted promise.
00:01:37 Remember what we did for the hasVoted question?
00:01:40 Well, we can do the same thing right here at the top.
00:01:43 by using the hasVoted action we created const hasVotedPromise is equal to hasVoted coming from libVoteActions to which we can pass an object where the
00:01:56 target ID is equal to underscore ID and the target type is equal to an answer.
00:02:01 So now we have that as well, but how do we get access to the number of upvotes and downvotes?
00:02:07 Well, let's pass it over into the answer card.
00:02:10 I'll see where this answer card is getting called by heading right here and searching for it.
00:02:17 And it's only called within the All Answers page.
00:02:21 Here, we're spreading out all of the properties of an answer.
00:02:24 And while it is true that before the answer didn't have the number of upvotes or downvotes, now it'll have it because we added it to the TypeScript interface.
00:02:34 And we can actually tree the answer as such by providing it the number of downvotes and upvotes.
00:02:40 So let's go ahead and use them right here.
00:02:42 We can just say upvotes and downvotes.
00:02:46 And with that in mind, the answer gets everything it needs to render the voting functionality.
00:02:52 So let's test it out.
00:02:54 If I click upvote, you can see upvote added successfully.
00:02:57 I can toggle it off.
00:02:59 That works.
00:03:00 What happens if I downvote?
00:03:02 That works too.
00:03:03 And I can, of course, switch from downvote to upvote and the number gets removed from the one that we removed and gets added to the other one.
00:03:13 This is perfect.
00:03:15 So now if somebody posts a bad question, we can downvote it.
00:03:19 And if somebody else makes a funny joke on that question, like they typically do on Stack Overflow, then we can upvote that joke right here and we can
00:03:28 downvote all of the other answers.
00:03:30 This is working like a charm and I think you can quickly see the benefit of taking some time to use the use hook to create this has voted promise action
00:03:40 to just make sure that our votes actions are agnostic of the type we apply that vote to, whether that's a question or an answer,
00:03:50 or whether that's an up vote or a down vote for that matter.
00:03:53 We were already thinking about the future when we started creating the model for the votes.
00:03:58 So with that in mind has now been fully implemented and you can see, and it is fully functional.
00:04:05 We can also track the number of votes right here on the question card.
00:04:10 So let me add a commit message of implement answer votes, commit and sync.
00:04:16 And that brings us to the end of the voting module.
00:04:18 This module was great, but trust me, the next one is even better.