Skip to content
🎉 Welcome to the new Aptos Docs! Click here to submit an issue.

3. Fetch Data from Chain

In the third chapter of the tutorial on building an end-to-end dapp on Aptos, you will be learning to fetch data from chain.

Our UI logic relies on whether the connected account has created a todo list. If the account has created a todo list, our app should display that list; if not, the app should display a button offering the option to create a new list.

For that, we first need to check if the connected account has a TodoList resource. In our smart contract, whenever someone creates a todo list we create and assign a TodoList resource to their account.

To fetch data from chain, we can use the Aptos TypeScript SDK. The SDK provides classes and functions for us to easily interact and query the Aptos chain.

To get started:

  1. Stop the local server if running.
  2. Import wallet from the wallet adapter React provider:
App.tsx
import { useWallet } from "@aptos-labs/wallet-adapter-react";
  1. Extract the account object from the wallet adapter:
App.tsx
function App (
	const { account } = useWallet();
)

The account object is null if there is no account connected; when an account is connected, the account object holds the account information, including the account address.

  1. Next, we want to fetch the account’s TodoList resource. Begin by importing useEffect by using import { useEffect } from "react"; Let’s add a useEffect hook to our file that would call a function to fetch the resource whenever our account address changes:
App.tsx
function App() {
  import { useEffect } from "react"
  ...
  useEffect(() => {
    fetchList();
  }, [account?.address]);
  ...
}
  1. Before creating our fetchList function, let’s also create a local state to store whether the account has a list:
App.tsx
function App (
  ...
  const [accountHasList, setAccountHasList] = useState<boolean>(false);
  ...
)

also import useState using import { useState, useEffect } from "react";

  1. Import MODULE_ADDRESS variable using import { MODULE_ADDRESS } from "./constants";. This is the address of the module we published in the previous chapter.
  2. Import aptosClient using import { aptosClient } from "./utils/aptosClient";. This is a client create-aptos-dapp created for us to interact with the chain.
  3. Our useEffect hook is calling a fetchList function; let’s create it:
App.tsx
const fetchList = async () => {
  if (!account) return [];
  const moduleAddress = MODULE_ADDRESS;
  try {
    const todoListResource = await aptosClient().getAccountResource(
      {
        accountAddress:account?.address,
        resourceType:`${moduleAddress}::todolist::TodoList`
      }
    );
    setAccountHasList(true);
  } catch (e: any) {
    setAccountHasList(false);
  }
};

The aptosClient().getAccountResource() expects an account address that holds the resource we are looking for and a string representation of an on-chain Move struct type.

  • account address - is the current connected account (we are getting it from the wallet account object)
  • Move struct type string syntax:
    • The account address who holds the move module
    • The module name the resource lives in = todolist
    • The resource name = TodoList

If the request succeeds and there is a resource for that account, we want to set our local state to true; otherwise, we would set it to false.

  1. Let’s update our UI based on the accountHasList state:
App.tsx
return (
  <>
    <TopBanner />
    <Header />
    <div className="flex items-center justify-center flex-col">
      {!accountHasList && (
        <div className="flex items-center justify-center flex-col">
          <Button>Add new list</Button>
        </div>
      )}
    </div>
  </>
);

We now have an Add new list button that appears only if the account doesn’t have a list.

Start the local server with npm run dev. You should see the Add new list button.

Next, let’s understand how to create a new list by submitting data to chain in chapter 4.