[SOLVED] useApiContract function doesn't work

Hello,
I canā€™t get data with useApiContract function in react-moralis.
Here is the my code, what is the problem?

import React from "react";
import { useMoralis } from "react-moralis";
import { useApiContract } from "react-moralis";
import contractAbi from "./contractAbi.json";

function App() {
  const { authenticate, isAuthenticated, user, logout, isAuthenticating } =
    useMoralis();

  const { runContractFunction, data, error, isLoading, isFetching } =
    useApiContract({
      address: PRIVATE,
      functionName: "getBalance",
      abi: contractAbi,
      params: {},
    });

  if (!isAuthenticated) {
    return (
      <div>
        <button onClick={() => authenticate()}>Authenticate</button>
      </div>
    );
  }

  return (
    <div>
      <h1>Welcome {user.get("ethAddress")}</h1>
      <button onClick={() => logout()} disabled={isAuthenticating}>
        Logout
      </button>
      <button onClick={() => runContractFunction()} disabled={isFetching}>
        Get balance
      </button>
      <h1> {data && <pre>{JSON.stringify(data)}</pre>} </h1>
    </div>
  );
}

export default App;

You may need to use useEffect

Thanks but there is no change in the data, it is static variable(for now).
Why should i use useEffect?

Maybe is not static. How do you know that is static?

I just want to display balance value on the screen from my smart contract and there is only 1 BNB(faucet) in there.
I tried useEffect but still doesnā€™t workā€¦

You can use getNativeBalance for that too, or the equivalent in react

This is the error what i get with my code: Failed to load resource: the server responded with a status of 400 ()

You could look in your browser network tab to see what was the request and what was the response

runContractFunction

Response: {ā€œcodeā€:141,ā€œerrorā€:ā€œReturned values arenā€™t valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced.ā€}

That could happen when ABI is not the right one

1 Like

Thanks, iā€™ll look at it

Hello again,
I tried on different smart contracts and still didnā€™t work.
Always given the same error:

{ā€œcodeā€:141,ā€œerrorā€:ā€œReturned values arenā€™t valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced.ā€}

Abi is perfectly true, i just copied and pasted it from bscscan.

if you try to use that directly in web3interface, how does it work?

https://admin.moralis.io/web3Api

1 Like

Hey, I had the exact same issue with useApiContract hook. What fixed it for me was adding the chain parameter to the hook.

const { runContractFunction, data, error } = useApiContract({
        address: CONTRACT_ADDRESS,
        functionName: 'totalSupply',
        abi: Abi,
        chain: 'rinkeby',
});
2 Likes

Hello, yeah i figured it out too yesterday.
The problem was the chain parameter as you said :slight_smile:
It is working now.

1 Like

Also had to add the chain here.
Thanks for the heads up!

The code for others

const jsonRpcOptions = {
  functionName: 'getNFTCollection',
  address: process.env.REACT_APP_RINKEBY_CONTRACT_ADDRESS_1155,
  abi: FilGoodNFT1155JSON.abi,
  chain: 'rinkeby'
  // params: {}
};

 const { runContractFunction: fetchNFTCollection } = useApiContract(jsonRpcOptions);
  1. Despite having a Provider at the top level - I had to call this with my appid & serverURl
   Moralis.start({
      appId: process.env.REACT_APP_MORALIS_APP_ID,
      serverUrl: process.env.REACT_APP_MORALIS_SERVER_URL
    });
  1. Wait for this to initialise:
  useEffect(() => {
    console.log('Checking if initialized');
    if (isInitialized) {
      getDisplayData();    }
  }, [isInitialized]);
  1. Then callled it with inbuilt chaining syntax to set vars I needed
    fetchNFTCollection()
      .then((nftCollectionData) => {
        //do stuff
          })
      })
      .catch((err) => {
        setTransactionState({
          ...transactionState,
          error: `Couldn't fetch NFT Collection: ${err}`
        });
      });
1 Like

You donā€™t need Moralis.start if youā€™re using <MoralisProvider>, and isInitialize will reflect MoralisProviderā€™s state when itā€™s ready. Check the settings in your provider. Are you on the latest Moralis / react-moralis versions?

const options = {
    abi: ABI,
    address: '0x7FBa4B8Dc5E7616e59622806932DBea72537A56b',
    functionName: 'totalSupply',
  };

  const { isInitialized } = useMoralis();
  const { runContractFunction, data } = useApiContract(options);

  useEffect(() => {
    if (isInitialized) {
      runContractFunction();
    }
  }, [isInitialized]);

  useEffect(() => {
    console.log('data', data);
  }, [data]);

You SHOULDNā€™t Need moralis start when using the Provider, However, the provider did not work for me.

Yes It was a clean install of all dependencies and up to date, so Iā€™m guessing there is a bug somewhere.

Happy to replicate this in a github / codepen

That would be good thanks.

How did you import Moralis when you needed to use Moralis.start?