useNFTBalances for contract

What does your code look like? What are you wanting to achieve?

hey glad …)

I am trying to insert into cards the nft staked metadata.
I can retrieve the nft tokenId staked and make a join like this

  async function getUserNftIds() {
    let options = {
      contractAddress: "0x....",
      functionName: "getUserNftIds",
      abi: abi,
      params: {
        user: account,
      },
    };

    const data = await contractProcessor.fetch({
      params: options,
      onSuccess: () => {
        console.log("Approval Received");
      },
      onError: (error) => {
        console.log("error", error);
      },
    });  
    const tokenIds = data[0];
    const tokenTimeStamps = data[1];
    const getTokenById = (tokenId) =>
      tokens.find((x) => x["token_id"].toString() === tokenId.toString());
    const tokenData = data[0].map((x, i) => ({
      timestamp: tokenTimeStamps[i],
      ...getTokenById(x),
    }));

component to return metadata from specifics tokenId

import { useEffect, useState } from "react";
import { useMoralisWeb3Api } from "react-moralis";
// import { useIPFS } from "./useIPFS";

export const getNFTImage = (tokenId) => {
  const { token } = useMoralisWeb3Api();
  const [NFTImage, setNFTImage] = useState([]);
  const [totalNFTs, setTotalNFTs] = useState();
  const [fetchSuccess, setFetchSuccess] = useState(true);
  const Web3Api = useMoralisWeb3Api();

  const fetchTokenIdOwners = async () => {
    const options = {
      address: "0x7de3085b3190b3a787822ee16f23be010f5f8686",
      token_id: tokenId,
      chain: "eth",
    };
    const tokenIdMetadata = await Web3Api.token.getTokenIdMetadata(options);
  console.log(tokenIdMetadata);
    setNFTImage(tokenIdMetadata );
  };

  return { NFTImage.result};
};

I would like to connect between the function and insert them into cards like this

        {data &&
          data.result.map((nft) => {
            return (
              <div key={nft.token_id} ...>

I hope it is understandable
thanks for your help

@glad, @cryptokid

hello, can you please provide me some help?

If you need to map over the returned data then with the way it’s set up you need to store data.result in a state variable first and use that.

Also with your getNFTImage, you need to make this a function component as you’re using hooks so call it NFTImage etc. And then pass the tokenId into it as a prop.

So your structure needs to be: function component with hooks (useState, etc.), fetch the data you need and pass that data into your return/render. E.g. fetch the token IDs, map over them to render out individual NFTImages which will then fetch the metadata associated with that ID and render the image from that.

I tried to use the useNFTBalance hooks and change the function and option there
like this

  const {
    fetch: getNFTImage,
    data,
    error,
    isLoading,
  } = useMoralisWeb3ApiCall(token.getTokenIdMetadata, {
    address: "0x7de3085b3190b3a787822ee16f23be010f5f8686",
    token_id: tokenId,
    chain: "eth",
  });

but I received an undefined answer, can I use it for this getTokenIdMetadata function
is there a simple way to do it instead of creating a hook from scratch?
I want to save time and errors.
thank you

Can you post your whole app code please to get a better idea.

thanks @glad, @cryptokid

I took the code from the nft marketplace bolierplate – minute 17
and did the changes as the video showed but for another function

import { useEffect, useState } from "react";
import { useMoralisWeb3Api, useMoralisWeb3ApiCall } from "react-moralis";
import { useIPFS } from "./useIPFS";

export const useTokenIdMetadata = (tokenId) => {
  // const { token } = useMoralisWeb3Api();
  const { resolveLink } = useIPFS();

  // const Web3Api = useMoralisWeb3Api();
  const { token } = useMoralisWeb3Api();
  const [NFTTokenIds, setNFTTokenIds] = useState([]);
  const [totalNFTs, setTotalNFTs] = useState();
  const [fetchSuccess, setFetchSuccess] = useState(true);
  const {
    fetch: getTokenIdMetadata,
    data,
    error,
    isLoading,
  } = useMoralisWeb3ApiCall(token.getTokenIdMetadata, {
    address: "0x7de3085b3190b3a787822ee16f23be010f5f8686",
    token_id: tokenId,
    chain: "eth",
  });
  useEffect(async () => {
    if (data?.result) {
      const NFTs = data.result;
      setTotalNFTs(data.total);
      setFetchSuccess(true);
      for (let NFT of NFTs) {
        if (NFT?.metadata) {
          NFT.metadata = JSON.parse(NFT.metadata);
          NFT.image = resolveLink(NFT.metadata?.image);
        } else if (NFT?.token_uri) {
          try {
            await fetch(NFT.token_uri)
              .then((response) => response.json())
              .then((data) => {
                NFT.image = resolveLink(data.image);
              });
          } catch (error) {
            setFetchSuccess(false);

            /*          !!Temporary work around to avoid CORS issues when retrieving NFT images!!
            Create a proxy server as per https://dev.to/terieyenike/how-to-create-a-proxy-server-on-heroku-5b5c
            Replace <your url here> with your proxy server_url below
            Remove comments :)
              try {
                await fetch(`<your url here>/${NFT.token_uri}`)
                .then(response => response.json())
                .then(data => {
                  NFT.image = resolveLink(data.image);
                });
              } catch (error) {
                setFetchSuccess(false);
              }
 */
          }
        }
      }
      setNFTTokenIds(NFTs);
    }
  }, [data]);

  return {
    getTokenIdMetadata,
    NFTTokenIds,
    totalNFTs,
    fetchSuccess,
    error,
    isLoading,
  };
};

and I also would like also to know how to call it
thanks

I’ll have a look at this for you later today or tomorrow.

thank you, this meant a lot to me. I am stuck with this function for a week already

I am not too sure about the rest of your app structure or how your program flow goes but this is an example for showing one NFT based on your code:

import { useEffect, useState } from 'react';
import { useMoralisWeb3Api, useMoralisWeb3ApiCall } from 'react-moralis';

function NFT(props) {
  const { token } = useMoralisWeb3Api();

  const {
    fetch: getTokenIdMetadata,
    data,
    error,
    isLoading,
    isFetching,
  } = useMoralisWeb3ApiCall(
    token.getTokenIdMetadata,
    {
      address: '0x7de3085b3190b3a787822ee16f23be010f5f8686',
      token_id: props.tokenId,
      chain: 'eth',
    },
    { autoFetch: true }
  );

  const [nft, setNft] = useState('');

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

  async function getMetadata(token_uri) {
    fetch(token_uri)
      .then((response) => response.json())
      .then((metadata) => {
        // example
        if (metadata.image.startsWith('ipfs://')) {
          metadata.image = metadata.image.replace(
            /^.*:\/\//i,
            'https://ipfs.io/ipfs/'
          );
        }

        const updatedNft = {
          ...data,
          metadata,
        };

        setNft(updatedNft);
      });
  }

  if (!nft) return null;

  return (
    <>
      {nft && (
        <div>
          <p>{nft.name}</p>
          <p>{nft.token_id}</p>
          <img src={nft.metadata.image} alt={nft.name} />
        </div>
      )}
    </>
  );
}

function App() {
  return (
    <>
      <NFT tokenId="1" />
    </>
  );
}

export default App;

I will try it, thank you very much

this is the message I am getting

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

this is how I am calling the function you created

import NFT  from "./getNFTImage";
.....
.....
 return (
    <>
        <div className={styles.card}>
          <NFT tokenId="1" />
</div>
</>

what am I missing ?

How have you moved the NFT component inside the getNFTImage file?

yes, I did.
and please after we finish this issue, I will be glad to get a book, course to extend my knowledge, since I feel like a noob

No, how have you put the NFT component in there? There is an issue with your import.

like I have sent you above

import NFT from "./getNFTImage";

and in the return section

  <NFT tokenId="1" />

nothing more

How have you put NFT inside getNFTImage?

It should be something like:

import NFT from "./NFT" - rename getNFTImage to NFT.jsx; this is a component

and inside that:

export default function NFT(props) {

thank you very much, it is working
there are some issues

Access to XMLHttpRequest at 'https://internal-api.moralis.io/api/functions/trackEvent' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
RESTController.js?8205:302      
    POST https://internal-api.moralis.io/api/functions/trackEvent net::ERR_FAILED 504

but you helped me a lot

That is an error that everyone is getting, which Moralis are trying to fix. It shouldn’t affect what you’re doing here, just ignore it.

No problem. I would recommend going through the React docs to fully grasp the basics before continuing. Basically you are trying to both learn the fundamentals of two different systems and also integrate both at once; that is quite difficult.

1 Like