(Previous Post: Part 1)
Follower/Following Counts
Steemit uses the concept of Followers to generate default feeds (e.g., @ned/feed).
We can get the count of followers and followings for an account by using the getFollowCount
API function (or getFollowCountAsync
if using Promises instead of Node-style callbacks):
function refreshAccountData(accountName) {
return steem.api.getAccountsAsync([accountName])
.then(function (result) {
...
steem.api.getFollowCountAsync(accountName)
.then(function (result) {
vm.$set(vm.userData, 'follower_count', result.follower_count)
vm.$set(vm.userData, 'following_count', result.following_count)
})
.catch(console.error)
...
For this to work correctly, add a follower_count
and following_count
property to the viewmodel's userData
object defined in Part 1 of this series:
...
userData: {
profile_image: "",
level: 0,
xp: 0,
power: 0,
following_count: 0,
follower_count: 0
}
...
Enumerating
Getting the actual list of followers/followings (as well as "muted" users that you never want to see content from) is a bit trickier. First, let's add some array properties to the viewmodel data to hold our lists:
data: {
user: 'jfollas',
userData: {
profile_image: "",
level: 0,
xp: 0,
power: 0,
following_count: 0,
follower_count: 0
},
followers: [],
following: [],
ignored: []
}
Now fetch the list of 'followers'. You have to chunk through followers 1000 items at a time, so we can use a generator function in JavaScript to retrieve the entire list:
let getFollowersList = P.coroutine(function* () {
let start = '', count = 0
vm.followers = []
do {
yield steem.api.getFollowersAsync(vm.user, start, 'blog', 1000)
.then(function (result) {
start = ''
count = result.length
for (let i = 0; i < count; i++) {
let entry = { name: result[i].follower }
start = entry.name
vm.followers.push(entry)
}
})
} while (count === 1000);
})
The 'following' list works the same, except it has to be chunked 100 items at a time instead of 1000:
let getFollowingList = P.coroutine(function* () {
let start = '', count = 0
vm.following = []
do {
yield steem.api.getFollowingAsync(vm.user, start, 'blog', 100)
.then(function (result) {
start = ''
count = result.length
for (let i = 0; i < count; i++) {
let entry = { name: result[i].following }
start = entry.name
vm.following.push(entry)
}
})
} while (count === 100);
})
Note that in both of these, we are using "blog" as the follow type. Also, on each iteration, we pass the last name from the previous iteration as the "start" value.
"Muted" users are maintained in a follow type of "ignore" instead of "blog". Otherwise, the function works identically to the getFollowingList
:
let getIgnoredList = P.coroutine(function* () {
let start = '', count = 0
vm.ignored = []
do {
yield steem.api.getFollowingAsync(vm.user, start, 'ignore', 100)
.then(function (result) {
start = ''
count = result.length
for (let i = 0; i < count; i++) {
let entry = { name: result[i].following }
start = entry.name
vm.ignored.push(entry)
}
})
} while (count === 100);
})
Okay, we have functions to retrieve the data and populate our viewmodel, but nothing is actually calling these functions. So, let's add function calls to our refreshAccountData()
logic:
function refreshAccountData(accountName) {
return steem.api.getAccountsAsync([accountName])
.then(function (result) {
...
getFollowersList()
getFollowingList()
getIgnoredList()
})
...
Displaying Results
Finally, let's add some HTML and Vue bindings to show our newly populated lists. Within the container
element, insert this block of html:
<div class="row">
<div class="col-4">
<h2>Followers</h2>
<ul class="list-group">
<li class="list-group-item" v-for="p in followers">
{{ p.name }}
</li>
</ul>
</div>
<div class="col-4">
<h2>Following</h2>
<ul class="list-group">
<li class="list-group-item" v-for="p in following">
{{ p.name }}
</li>
</ul>
</div>
<div class="col-4">
<h2>Muted</h2>
<ul class="list-group">
<li class="list-group-item" v-for="p in ignored">
{{ p.name }}
</li>
</ul>
</div>
</div>
Example (names have been obfuscated):
(Next Post: Part 3)