Log 02 — Every Vote Counts
This is a continuation of my NodeJS dev log series. If you haven’t read the introductory post that explains what I’m trying to accomplish with this project, you can read that here.
If you’d like to see the code for yourself, the entire project is available in my GitHub repo.
Aesthetic Changes
A very small change that I made was to the scroll bars within the Topic box when there are more than 4 Reasons listed. They still look pretty weird, so they’ll change again soon most likely. I also added comments to most of the important controllers — nothing too interesting.

Adding Votes
The first step I wanted to take with this just involved iterating the vote counters when clicked. Super simple with a little bit of JavaScript, although I had to do some weird DOM querying for it to work properly at first. This wasn’t useful, of course, because nothing was updated on the back end and the counters would return to their original state (1) when the page is refreshed.

Next, I knew I needed to implement a few of things — a way to update the votes in the back-end, so that the changes will persist. Also, I wanted the reasons to be sorted in descending order (highest voted at the top), and a way to track user responses to prevent multiple votes and allow them to change their mind.
Actually Adding Votes
This involved a couple things, as I mentioned earlier:
- GET / POST endpoints for Reason vote counts
- Sorting Reasons by count when requested with GET
While experimenting with this, I noticed that clicking ‘Add’ with nothing in the textbox either A) Added a Reason with its UID as the text or B) added a Reason with the same text that was submitted previously. That’s something that I’ll fix with input validation down the road — not too important for now.
My solution to incrementing the vote count was to treat a mouse click in the count box as an attempt to add a new Reason in terms of the API call. The data provided in the API calls are slightly different compared to the addReason function, but otherwise the structure is the same:

That said, the similarity between the two functions and the extremely redundant If/Else structure leaves a lot of room for streamlining later.
Because I’m making the same API call, I needed to modify the back-end function that results from it to accommodate ‘adding’ a Reason that already exists. Once the Mongoose search through the database comes back with the existing Reason, it was easy to add 1 to its current count and then return the entire new Topic that it is associated with.

So voting works now. It doesn’t allow for duplicate Reasons within different Sides, but that’s unlikely to happen and an unimportant detail, at least for now. Now that the numbers are updating properly, I need to use them to sort the Reason list appropriately.
I achieved this by using a very simple Array.sort logic within the get() function. Again, the three-boxed nature of the logic is sloppy since it’s the same function call, but I have yet to implement a less redundant method. Maybe I can create an array of each Side and then async.each() through it? Sounds possible. That will come later.

And this is the result:

This could definitely use some kind of animation to demonstrate a change in order, or not refresh automatically to prevent ‘losing’ the option that you just voted for, but this is another thing that’s on the ‘not important enough to do right now’ list that is well-documented with these articles.
But this presents a problem that bumps up the difficulty of this project a little bit: handling users and validating their input. As I laid out earlier, I’d like to have an account-less experience, for multiple reasons. To achieve this, I think that a user token that is automatically assigned to each user would be a straightforward and non-intrusive way of keeping track of user responses. This will help with ensuring that people only vote once per Topic, to a degree. In the future, it would also be interesting for the user to be able to see a history of their responses.
I’ll get into that next time. Thanks for reading.

