How to create a table with javascript from hive engine's data.

in HK UNIVERSITY5 months ago

So this serves as an introduction on how to read info from hive-engine api's to create a functional website: Our plan is to create a table that shows the top 20 holders of a certain token.

First we create an index.html file with the following code:

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
  
</body>
</html>

Now we need to set the skeleton for our table adding these few lines between the body tags:

<main>
    <table>
        <thead>
            <tr>
                <th>Users</th>
                <th>BUDS</th>
            </tr>
        </thead>
        <tbody id="tableBody">
        </tbody>        
    </table>
  </main>

Then finally:

<!DOCTYPE html>
<html lang="en">
   
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <main>
        <table>
            <thead>
                <tr>
                    <th>Users</th>
                    <th>BUDS</th>
                </tr>
            </thead>
            <tbody id="tableBody">
            </tbody>        
        </table>
      </main>
</body>
</html>

We can open the file in a browser and check everything is okay:

image.png

Now we need to get our data from hive's api: one way to do that is using the fetch function: We need to create a source.js file and add these few lines of code:

async function findData() {
    const response = await fetch("https://api.hive-engine.com/rpc/contracts", {
      method: "POST",
      headers: { "Content-type": "application/json" },
      body: JSON.stringify({
        jsonrpc: "2.0",
        method: "find",
        params: {
          contract: "tokens",
          table: "balance",
          query: {},
        },
        id: 1,
      }),
    });
    const responseJson = await response.json();
    const data = responseJson.result
    console.log(data);
  }
  
  findData()

Basically it's a an async/await function that contains a fetch method which allows us to do get and post requests to the api.

Now we need to link the index file to our html file before the body tag:

<script type="text/javascript" src="index.js"> </script> 

<!DOCTYPE html>
<html lang="en">
   
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="source.js"> </script>
    <title>Document</title>
</head>
<body>
    <main>
        <table>
            <thead>
                <tr>
                    <th>Users</th>
                    <th>BUDS</th>
                </tr>
            </thead>
            <tbody id="tablebody">
            </tbody>        
        </table>
      </main>
</body>
</html>

Now we will go back to the javascript file and replace the query for:
query: {"symbol":"BUDS", 'balance': { '$ne' : "0" }},
So we can get fillter out from the data those who have 0 buds:

image.png

Well now we have the data, but we need to insert it into the DOM. So we will add some DOM manipulation functions to our main asynchronic function

const tableBody = document.getElementById("tablebody");  //finds the element with the id "tablebody"

Then we are gonna need to create some rows for every user in the top 20
we can solve this by using a for loop:

for (i = 0; i < data.length; i++) {
    const row = document.createElement("tr"); //creates a row
    const user = document.createElement("td"); //creates a cell 
    const balance = document.createElement("td"); //creates a cell
  }

Then these lines add text to the cell:

 //these lines add text to the cells
    user.textContent = data[i].account;
    balance.textContent = data[i].balance;

Then we have:

for (i = 0; i < data.length; i++) {
    const row = document.createElement("tr"); //creates a row
    const user = document.createElement("td"); //creates a cell inside the row
    const balance = document.createElement("td"); //creates a cell
    user.textContent = data[i].account;
    balance.textContent = data[i].balance;
  }

Then we append the elements we created to the table:

    row.append(user);
    row.append(balance);
    tableBody.append(row);

Which results in:

const tableBody = document.getElementById("tablebody");
for (i = 0; i < 20; i++) {
    const row = document.createElement("tr"); //creates a row
    const user = document.createElement("td"); //creates a cell inside the row
    const balance = document.createElement("td"); //creates a cell
    user.textContent = data[i].account;
    balance.textContent = data[i].balance;
    row.append(user);
    row.append(balance);
    tableBody.append(row);
  }

Finally:

async function findData() {
    const response = await fetch("https://api.hive-engine.com/rpc/contracts", {
      method: "POST",
      headers: { "Content-type": "application/json" },
      body: JSON.stringify({
        jsonrpc: "2.0",
        method: "find",
        params: {
          contract: "tokens",
          table: "balances",
          query: {"symbol":"BUDS", 'balance': { '$ne' : "0" }},
        },
        id: 1,
      }),
    });
    const responseJson = await response.json();
    const data = responseJson.result
    console.log(data);

    const tableBody = document.getElementById("tablebody");
    for (i = 0; i < 20; i++) {
      const row = document.createElement("tr"); //creates a row
      const user = document.createElement("td"); //creates a cell inside the row
      const balance = document.createElement("td"); //creates a cell
      user.textContent = data[i].account;
      balance.textContent = data[i].balance;
      row.append(user);
      row.append(balance);
      tableBody.append(row);
    }
  }
  
  findData()

Then we get:

image.png

As you can see we got "20" BUDS holders but they aren't ordered from highest to lowest... we aren't filtering the data, this is easily solved anyway:

we had this variable
const data = responseJson.result

we can change it to

let data = responseJson.result
data = data.sort((a, b) => b.balance - a.balance);

data.sort((a, b) => b.balance - a.balance)
this javascript method orders the elements in the array comparing the balances in each of them.

Then finally:

image.png

To learn more about what information can you get (and how) from hive-engine's api you can check this:
https://hive-engine.github.io/engine-docs/tables/#tables-tokens

Here's another way to do this applying sscjs instead of the fetch function:
https://peakd.com/hive-104341/@fefe99/how-to-use-sscjs-library-to-find-info-in-hive-engine

Another way would be to use axios or an XMLhttprequest.

Sort:  

This is great, very clear instructions.

!PIZZA
!ALIVE

@fefe99! You Are Alive so I just staked 0.1 $ALIVE to your account on behalf of @thoth442. (6/10)

The tip has been paid for by the We Are Alive Tribe through the earnings on @alive.chat, feel free to swing by our daily chat any time you want.

Thanks :)

!PIZZA

Congratulations @fefe99! You have completed the following achievement on the Hive blockchain and have been rewarded with new badge(s):

You published more than 10 posts.
Your next target is to reach 20 posts.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

To support your work, I also upvoted your post!

Support the HiveBuzz project. Vote for our proposal!

Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!

Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).

You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support. 
 

PIZZA! PIZZA!

PIZZA Holders sent $PIZZA tips in this post's comments:
@fefe99(1/10) tipped @thoth442 (x1)
thoth442 tipped fefe99 (x1)

Please vote for pizza.witness!

Hi @fefe99

Do you know you could have used #diy tag for this post to earn some BUIDL tokens?

In case you are not aware, read this post to know the kinds of content you could post using #diy tag.

Because most people are not aware of the potential of BUIDL token, it can be bought at very cheap price now.