Write a Steemit Web App: Part 8 - Retrieving Content with getState()

in #steemdev7 years ago (edited)

(Previous Post: Part 7)

javascriptlogo.png

Steemit is a content platform. So, let's begin to look into how to retrieve content using Steem.js.

Introducing getState()

If you have been paying attention, the Steemit.com website changes the URL in the address bar of your browser as you navigate around the site. Drill into the #steemdev category and click on the "trending" link at the top, and you'll get a list of trending posts for that category.

But take note of the URL: /trending/steemdev

trending.PNG

Under the covers, Steemit.com is using the getState() API function to retrieve the content, which is sort of a Swiss Army Knife for mass content retrieval.

In the source code on GitHub, this API function is described in the header file as:

This API is a short-cut for returning all of the state required for a particular URL with a single query.

We can use this function, too, in our own apps.

JavaScript Example

Let's first see what this API returns for the same path as the screenshot above:

steem.api.getStateAsync('trending/steemdev') 
  .then(r => console.log(JSON.stringify(r,null,2)))
  .catch(console.log)


Results (about 30,000 lines of JSON, but trimmed here):

{
  "current_route": "trending/steemdev",
  "props": {
    "id": 0,
    "head_block_number": 14023166,
    "head_block_id": "00d5f9fe8c5020703027c895c645c6cb36daf66f",
    "time": "2017-07-26T14:17:00",
    ...
  },
  "tag_idx": {
    "trending": [
      "",
      "photography",
      "steemit",
      "life",
      ...
    ]
  },
  "tags": {},
  "content": {
    "alexpmorris/ultimate-steemit-post-vote-slider-and-past-payout-monetizer-and-next-here-comes-steemtube": {
      "id": 7749261,
      "author": "alexpmorris",
      "permlink": "ultimate-steemit-post-vote-slider-and-past-payout-monetizer-and-next-here-comes-steemtube",
      ...
    },
    "almost-digital/dsteem-playground": {
      "id": 8059239,
      "author": "almost-digital",
      "permlink": "dsteem-playground",
      ...
    },
    ...
  },
  "accounts": {
    "alexpmorris": {
      "id": 27017,
      "name": "alexpmorris",
      ...
    },
    "almost-digital": {
      "id": 180270,
      "name": "almost-digital",
      ...
    },
    "ausbitbank": {
      "id": 16662,
      "name": "ausbitbank",
      ...
    },
    ...
  },
  "pow_queue": [],
  "witnesses": {},
  "discussion_idx": {
    "steemdev": {
      "category": "",
      "trending": [
        "good-karma/esteem-filters-community-input-om0vmqj9sw",
        "ausbitbank/steemvids-alpha-update",
        "good-karma/good-karma-witness-update-22nd-july-2017-ulf0cx9y6o",
        "almost-digital/dsteem-playground",
        ...
      ],
      "payout": [],
      "payout_comments": [],
      "trending30": [],
      "updated": [],
      "created": [],
      "responses": [],
      "active": [],
      "votes": [],
      "maturing": [],
      "best": [],
      "hot": [],
      "promoted": [],
      "cashout": []
    }
  },
  "witness_schedule": {
    "id": 0,
    "current_virtual_time": "211660231715735847283804039",
    "next_shuffle_block_num": 14023170,
    ...
  },
  "feed_price": {
    "base": "1.544 SBD",
    "quote": "1.000 STEEM"
  },
  "error": ""
}


This single call provides A LOT of information, including the list of content being requested, the latest Dynamic Global Properties, the latest Account Data for the authors included in the results, and the current feed price. In other words, all of the information that the Condenser (Steemit.com) needs to render the summary list when you clicked on the /trending/steemdev page (they deliver everything in one result to save the need for multiple calls).

The JSON for one individual post:

"alexpmorris/ultimate-steemit-post-vote-slider-and-past-payout-monetizer-and-next-here-comes-steemtube": {
      "id": 7749261,
      "author": "alexpmorris",
      "permlink": "ultimate-steemit-post-vote-slider-and-past-payout-monetizer-and-next-here-comes-steemtube",
      "category": "steemit",
      "parent_author": "",
      "parent_permlink": "steemit",
      "title": "Ultimate STEEMIT: Minnow Post Vote Slider and Past Payout Monetizer Script... and next, here comes SteemTUBE!!! 😲",
      "body": "Back in May I attended the ...",
      "json_metadata": "{\"tags\":[\"steemit\",\"steem\",\"...",
      "last_update": "2017-07-21T15:59:45",
      "created": "2017-07-20T19:31:15",
      "active": "2017-07-26T10:09:21",
      "last_payout": "1970-01-01T00:00:00",
      "depth": 0,
      "children": 129,
      "net_rshares": "41126108310099",
      "abs_rshares": "42006702146358",
      "vote_rshares": "40325568458953",
      "children_abs_rshares": "44180630728995",
      "cashout_time": "2017-07-27T19:31:15",
      "max_cashout_time": "1969-12-31T23:59:59",
      "total_vote_weight": 6492920,
      "reward_weight": 10000,
      "total_payout_value": "0.000 SBD",
      "curator_payout_value": "0.000 SBD",
      "author_rewards": 0,
      "net_votes": 254,
      "root_comment": 7749261,
      "max_accepted_payout": "1000000.000 SBD",
      "percent_steem_dollars": 0,
      "allow_replies": true,
      "allow_votes": true,
      "allow_curation_rewards": true,
      "beneficiaries": [],
      "url": "/steemit/@alexpmorris/ultimate-steemit-post-vote-slider-and-past-payout-monetizer-and-next-here-comes-steemtube",
      "root_title": "Ultimate STEEMIT: Minnow Post Vote Slider and Past Payout Monetizer Script... and next, here comes SteemTUBE!!! 😲",
      "pending_payout_value": "206.739 SBD",
      "total_pending_payout_value": "0.000 STEEM",
      "active_votes": [
        {
          "voter": "xeldal",
          "weight": 37948,
          "rshares": "318328302844",
          "percent": 360,
          "reputation": "8294734761009",
          "time": "2017-07-21T11:00:57"
        },
        ...
      ],
      "replies": [],
      "author_reputation": "17890018830960",
      "promoted": "0.000 SBD",
      "body_length": 12518,
      "reblogged_by": []
    },


Even though it looks like all of the information about the post is captured in this data, the body property will be truncated. So, if you need to retrieve the entire body of the content, then you will have to use another API call:

steem.api.getContent(author, permlink)

Note: This is similar to how clicking on a title in the Condenser displays the content in a separate popup.

Possible Paths

Here are some of the useful paths that can be provided to the getState(path) function call:

  • created/{tag}: "New" content for the category. Remove /{tag} to get content from across all tags.
  • hot/{tag}: "Hot" content for the category. Remove /{tag} to get content from across all tags.
  • trending/{tag}: "Trending" content for the category. Remove /{tag} to get content from across all tags.
  • promoted/{tag}: "Promoted" content for the category. Remove /{tag} to get content from across all tags.
  • active/{tag}: "Active" content for the category. Remove /{tag} to get content from across all tags.
  • {@user}/feed: The feed for the user (based on who that user follows)
  • {@user}/blog: The blog for the user (including posts that the user Resteemed)

What's Missing?

getState() is useful to retrieve the first page of results and all of the data that is needed to render that in a summary view. However, you'll notice that on Steemit.com, as you scroll down through the list, additional pages of content are requested on-the-fly. This is achieved via other API calls, which we'll explore later.

javascriptlogo.png

(Next Post: Part 9)

Sort:  

is there a way to regex or wildcard the title search

Nice one again, I keep learning stuff that I can use in my own Steemit app. Keep it up!