TypeError: Cannot read properties of undefined (reading 'call')

I get this error while using react-moralis to fetch the tokenURI of a NFTContract that i deploy on a localchain using Hardhat. Here is the ‘index.js’ code:

const { runContractFunction: getTokenURI } = useWeb3Contract({
    abi: nftAbi.functions["tokenURI(uint256)"],
    contractAddress: nftAddress,
    functionName: "tokenURI",
    params: {
        tokenId: tokenId,
    },
})

async function updateUI() {
    const tokenURI = await getTokenURI({
        onSuccess: (data) => console.log(data),
        onError: (error) => console.log(error),
    })
}

useEffect(() => {
    if (isWeb3Enabled) {
        updateUI()
    }
}, [isWeb3Enabled])

In the ‘_app.js’ i add the MoralisProvider stuff:

<MoralisProvider
            serverUrl={process.env.NEXT_PUBLIC_SERVER_URL}
            appId={process.env.NEXT_PUBLIC_APP_ID}
        >
            <Header />
            <Component {...pageProps} />
</MoralisProvider>

And to enable web3 i use the <ConnectButton moralisAuth={false} /> in the Header.

Is your wallet on the right chain/network for your local dev chain? And check all the options/params you’re using for calling tokenURI.

I Think so, because after i connect via the ConnectButton i see the 10000ETH in my balance that Hardhat set by default to the generated wallet, the function i’m tryng to call is this:

function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
    require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

    if (revealed == false) {
        return notRevealedUri;
    }

    string memory currentBaseURI = _baseURI();
    return
        bytes(currentBaseURI).length > 0
            ? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))
            : "";
} 

I check the params by console.logging them and they are right, it gave the same error also if i try to fetch other functions :frowning:

I have the same problem, did you find a solution?

What is the line that gives that error?

This one, although for me it’s in a try{}catch{}, but the logging of the tokenURI()'s return value keeps reporting undefined

Maybe you can check somehow the value of the returned data if is undefined or not

I have, I have my test file running smooth, it’s returning the tokenURI as a string just like it should

What is the error that you get then?

instead of returning the string that it should, it returns ‘undefined’

Can you post more of your code; make sure to include the parameters you’re using for the read function (contract address, chain, tokenId, etc.).

For sure, here we go:

Server URL : https://c10qqeiy1pia.usemoralis.com:2053/server
chainID is 31337

Here is my component NFTBox.js which is supposed to render an NFT for sale :

import { useEffect, useState } from "react"
import { useWeb3Contract, useMoralis } from "react-moralis"
//import nftMarsketplaceAbi from "../constants/NftMarsketplace.json"
import nftAbi from "../constants/MintOneToken.json"

export default function NFTBox({ price, nftAddress, tokenId, marsKetplaceAddress, seller }) {
  //const [imageURI, setImageURI] = useState("")
  const { isWeb3Enabled } = useMoralis()

  const { runContractFunction: getTokenURI } = useWeb3Contract({
    abi: nftAbi,
    contractAddress: nftAddress,
    functionName: "tokenURI",
    params: {
      tokenId: tokenId,
    },
  })

  async function updateUI() {
    // get tokenURI
    try {
      const tokenURI = await getTokenURI()
      console.log(tokenURI)
    } catch (e) {
      console.log(e)
    }

    // using image tag from the tokenURI
  }

  useEffect(() => {
    if (isWeb3Enabled) {
      updateUI()
    }
  }, [isWeb3Enabled])
}

Here is the abi of the contract upon which the tokenURI function

[{"type":"constructor","payable":false,"inputs":[]},{"type":"error","name":"MarsKetplace__AlreadyListed","inputs":[{"type":"address","name":"nftAddress"},{"type":"uint256","name":"tokenId"}]},{"type":"error","name":"MarsKetplace__NotApproved","inputs":[]},{"type":"error","name":"MarsKetplace__NotListed","inputs":[{"type":"address","name":"nftAddress"},{"type":"uint256","name":"tokenId"}]},{"type":"error","name":"MarsKetplace__NotOwner","inputs":[]},{"type":"error","name":"MarsKetplace__PriceCantBeZero","inputs":[]},{"type":"error","name":"MarsKetplace__PriceNotMet","inputs":[{"type":"address","name":"nftAddress"},{"type":"uint256","name":"tokenId"},{"type":"uint256","name":"price"}]},{"type":"event","anonymous":false,"name":"NFTBought","inputs":[{"type":"address","name":"buyer","indexed":true},{"type":"address","name":"nftAddress","indexed":true},{"type":"uint256","name":"tokenId","indexed":true},{"type":"uint256","name":"price","indexed":false}]},{"type":"event","anonymous":false,"name":"NFTDeleted","inputs":[{"type":"address","name":"nftAddress","indexed":true},{"type":"uint256","name":"tokenId","indexed":true}]},{"type":"event","anonymous":false,"name":"NFTListed","inputs":[{"type":"address","name":"seller","indexed":true},{"type":"address","name":"nftAddress","indexed":true},{"type":"uint256","name":"tokenId","indexed":true},{"type":"uint256","name":"price","indexed":false}]},{"type":"function","name":"buyNFT","constant":false,"stateMutability":"payable","payable":true,"gas":29000000,"inputs":[{"type":"address","name":"nftAddress"},{"type":"uint256","name":"tokenId"}],"outputs":[]},{"type":"function","name":"cancelListing","constant":false,"payable":false,"gas":29000000,"inputs":[{"type":"address","name":"nftAddress"},{"type":"uint256","name":"tokenId"}],"outputs":[]},{"type":"function","name":"getBalance","constant":true,"stateMutability":"view","payable":false,"gas":29000000,"inputs":[],"outputs":[{"type":"uint256"}]},{"type":"function","name":"getListing","constant":true,"stateMutability":"view","payable":false,"gas":29000000,"inputs":[{"type":"address","name":"nftAddress"},{"type":"uint256","name":"tokenId"}],"outputs":[{"type":"tuple","components":[{"type":"uint256","name":"price"},{"type":"address","name":"seller"}]}]},{"type":"function","name":"listNft","constant":false,"payable":false,"gas":29000000,"inputs":[{"type":"address","name":"nftAddress"},{"type":"uint256","name":"tokenId"},{"type":"uint256","name":"price"}],"outputs":[]},{"type":"function","name":"updateNFTPrice","constant":false,"payable":false,"gas":29000000,"inputs":[{"type":"address","name":"nftAddress"},{"type":"uint256","name":"tokenId"},{"type":"uint256","name":"newPrice"}],"outputs":[]},{"type":"function","name":"withdrawSales","constant":false,"payable":false,"gas":29000000,"inputs":[],"outputs":[]}]

Here is index.js:

import Head from "next/head"
import Moralis from "moralis"
import styles from "../styles/Home.module.css"
import mars from "./mars.jpg"
import { useMoralisQuery } from "react-moralis"

import NFTBox from "../components/NFTBox"

function Home(props) {
  const { data: listedNfts, isFetching: fetchingListedNfts } = useMoralisQuery(
    //table name
    "ActiveNFT",
    // function for query
    (query) => query.limit(10).descending("tokenId")
  )
  console.log(listedNfts)

  return (
    <div backgroundImage={mars} height="100vp">
      <Head>
        <title>The MarsKetplace</title>
        <meta name="description" content="NFT MarsKetplace" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <h1 className="font-bold text-3xl">Own your plot on MARS</h1>
      <h3 className="text-2xl">Here are the current NFTs for sale</h3>
      <div>
        <p>Display NFT here</p>
        {fetchingListedNfts ? (
          <div>Loading...</div>
        ) : (
          listedNfts.map((nft) => {
            console.log(nft.attributes)
            const { price, nftAddress, tokenId, marsKetplaceAddress, seller } = nft.attributes
            return (
              <div>
                Price : {price}, NFT address : {nftAddress}, Token ID : {tokenId}, Seller :{seller}
                <NFTBox
                  price={price}
                  nftAddress={nftAddress}
                  tokenId={tokenId}
                  marsKetplaceAddress={marsKetplaceAddress}
                  seller={seller}
                  key={`${nftAddress}${tokenId}`}
                />
              </div>
            )
          })
        )}
      </div>
    </div>
  )
}

export async function getServerSideProps(context) {
  // reads the api key from .env.local and starts Moralis SDK
  await Moralis.start({ apiKey: process.env.MORALIS_API_KEY })

  return {
    props: {},
  }
}

export default Home

I am correctly connected to my metamask, using the automatically deployed account from hardhat (on localhost 8545).

Here is the console’s printing result when loading the page after running yarn dev:

[ParseObject]
react_devtools_backend.js:4082 {marsketplaceAddress: '0xe7f1725e7734ce288f8367e1bb143e90bb3f0512', nftAddress: '0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0', price: '1000000000000000000', tokenId: '0', seller: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', …}

undefined                                                     NFTBox.js?3c6a:23 

The last line next to undefined highlights console.log(tokenURI) on the NFTBox.js component.

I’ve tried removing the try/catch, same result ; I minted and listed a new NFT with a new tokenURI, same result.

NVM !!
I figured out what happened, I mis-wrote a function in the script that is in charge of updating the front-end abi .json file. It could not find the data as the abi was not correct.

Issue closed on my side :slight_smile: