Render a Data Table from Contract VIEW Methods

Iterate over contract addresses and fetch their data to render a data table. Learn this useful React hook pattern to implement this in your own dApp.

Getting Started

Follow the Project Setup instructions to start the project in your local machine and try the recipes yourself. You can also clone or navigate the repo to get just what you need.

Fetching the latest market ids

For Prompt Wars, this table is rendered in the /previous-rounds URL. It will load this page component:

Let's dive into pulse.promptWars.getLatestMarketId():

As you can see, it is creating a guest connection to get data from a Rust NEAR contract get_markets_list VIEW method.

Creating the game contracts

This contract is a games factory implementation that stores only the game IDs after their contract accounts are created:

Fetching the game contracts IDs

The VIEW methods are in the same contract suite, but in this file:

This way, we are able to get an array of game IDs which we'll use to fetch their storage metadata.

Game metadata storage

Pay attention to pub struct MarketData and its type definitions. We should have VIEW and CHANGE methods to modify some of these properties and get them later:

Getting game metadata

We add VIEW methods to set these properties, for example get_market_data:

Setting immutable storage values at contract initialization

Some of the storage values are set when the contract is initialized, meant to NOT be modified later:

Deploy the factory contract

Run sh build.sh to build the factory contract:

and then deploy it:

near deploy --wasmFile target/wasm32-unknown-unknown/release/market_factory.wasm --accountId $NEAR_PROMPT_WARS_FACTORY_ACCOUNT_ID

Creating game contracts

Now that there's an on-chain factory contract, we should be able to create new games on the server side:

Getting contract metadata from the client side

When a new game is created, the factory contract should return the game IDs with get_markets_list as we explained earlier. Once you can get a game ID, you should also be able to get its metadata:

Iterate over game IDs, fetch the data and render the table

Finally, we should be able to render a table component with the contract values.

Notice how the table row component is wrapped with a context controller:

{markets.map((marketId) => (
          <NearPromptWarsMarketContractContextController marketId={marketId} key={marketId}>
            <PreviousRoundsTableRow marketId={marketId} />
          </NearPromptWarsMarketContractContextController>
        ))}

The Table Row

useNearPromptWarsMarketContractContext hook will help us to organize the VIEW methods implementation better and render the data in the td elements:

Getting game contract values for each row

Lastly, this is the implementation of a Promise.all call to get all the on-chain values needed for the table and other game info components:

Last updated