Last time we learned how to calculate a user's reputation. Let's kick it up a notch this time and do something a little more complicated. We'll answer a question I bet many Steemians are curious to know!
"Who upvoted me the most?"
But first, let me tell you that soon you won't even have to calculate this yourself anymore. and I are very busy working on a website where you can check all kinds of statistics like this very easily. We're going to launch our Beta version very soon but first we need a name for the app. You can help us by suggesting a great name, and you can even win $20 SBD doing so!
Anyway, in the meantime I'll explain how you can answer this question yourself by using the SteemJS library.
Fetching a user's posts
First we have to grab our posts so that we can look at all the upvotes.
To get our posts we use Steem.api.getDiscussionsByAuthorBeforeDate(). It expects four arguments:
usernamestartPermlink(optional) Permlink to a post before which we want to get our postsbeforeDateDate before which we want to get our posts*limitAmount of posts (max 100)
* beforeDate seems to be broken, no matter what date we enter it returns the latest posts.
To keep it simple for now, we'll just grab the most recent 100 posts. Even if you posted a new blog every day it would still have data from the past 3 months, so that will do for now.
The second argument (startPermlink) can be null because we don't need to grab posts before any other post. This is something we will need if we want more than the last 100 posts, which we'll do in a later tutorial.
Because the beforeDate is broken we will just pass along January 1, 2100 so our app will be safe to use for the next 83 years. After that it's time to find a new hobby folks!
Get posts:
Steem.api.getDiscussionsByAuthorBeforeDate('pilcrow', null, '2100-01-01T00:00:00', 100)
.then(posts => {
// do something with posts here
});
Getting all the upvoters on a post
Once we have the posts, it's time to look at who upvoted each. For this we use the property active_voteson each post.
A partial screenshot of a post's properties. active_votes allows us to see who voted on the post. And yes, I self-voted 😬
So let's see how we can make a list of all upvoters on post:
function getUpvoters(post) {
return post.active_votes.map(upvote => upvote.voter);
}
For the post in the screenshot this will result in the following:
['pharesim', 'team', 'banjo', 'skririm', 'minnowsupport', 'pilcrow', 'itswetz', 'muxxybot', 'maestroq']
Adding upvoters for all posts together.
Now that we have a function to get all upvotes for one post, we can do this for all our posts. To combine them in one big array we use a reduce function. It starts with an empty array (all), and for every post we loop through it adds the upvoters on that post to it (all.concat(upvoters)).
function getAllUpvoters(posts) {
return posts.reduce((all, currentPost) => {
const upvoters = getUpvoters(currentPost)
return all.concat(upvoters);
}, []);
}
We can do this in a one-liner but I like to keep my code a bit readable
Now we have a much longer array with all upvoters on all our posts combined. If someone upvoted us twice, they will appear in this array twice. Which leaves us with the task of counting the occurrences.
Counting the amount of upvotes per user
To add up all vote counts per user, we use another reduce function. It starts with an empty object, and every time we loop over an upvoter we want to add its count to the object.
If we've counted the upvoter before it already has a count, otherwise we start at 1. Here's a quick one-liner to do that:
upvoteCounts[upvoter] = (upvoteCount[upvoter] || 0) + 1;
Meaning that if the upvoter is already in the object we grab that value, if he's not we start with 0. Then we add 1 to that number and write it back into the object. The complete function looks like this:
function countUpvoters(allUpvoters) {
return allUpvoters.reduce((upvoteCounts, upvoter) => {
upvoteCounts[upvoter] = (upvoteCounts[upvoter] || 0) + 1;
return upvoteCounts;
});
}
Putting it all together
Now that we have all the functions to calculate the amount of upvotes on our last 100 posts, let's put it together.
Steem.api.getDiscussionsByAuthorBeforeDate('pilcrow', null, '2100-01-01T00:00:00', 100)
.then(posts => {
const allUpvoters = getAllUpvoters(posts);
return countUpvoters(allUpvoters);
});
The result
And this is what the result will look like:
{
"pharesim": 12,
"team": 2,
"banjo": 15,
"skririm": 1,
"minnowsupport": 15,
"pilcrow": 26,
"itswetz": 1,
"muxxybot": 13,
"maestroq": 1,
"proctologic": 6,
"nomadnessie": 1,
"sjennon": 2,
"personz": 1,
...
}
Demo on jsFiddle
I also made a jsFiddle example of this so you can play around with it. Enter your own username on line 4 (whoUpvotedMe('yourUserNameHere')) and see who upvoted you the most!
There's all kinds of other things you can do with this of course. You could keep the count in an array of follower objects instead so that you can sort them, for example. This is just a basic example of what you can do with information from the SteemJS API.
Was this useful to you? Do you have any suggestions or improvements? Let me know in the comments! ⬇