Write a Steemit Web App: Part 2 - Followers and Following

in #steem-dev7 years ago (edited)

(Previous Post: Part 1)

Follower/Following Counts

Steemit uses the concept of Followers to generate default feeds (e.g., https://steemit.com/@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):
steemit-tutorial-2.PNG

(Next Post: Part 3)

Sort:  

is there anyway to use the steemit api to post a story to steemit with javascript

steem.broadcast.comment() - creates posts and comments.

you can find an example here: SteemDocs

Thanks! I'm writing this series as I explore the API myself, so I haven't gotten to content creation yet (but was going to be working on that for an upcoming post).

Hi @jfollas, nice tutorials.
May I put them on SteemDocs? I'm collecting dev resources there..

I have no problems with that. Just hoping that I have the bandwidth available to keep writing this series.

Loading...

Can't get it to display lists. Is there a functioning example of this code anywhere I can review?