[SOLVED] Displaying nfts after calling fetchNFTs

I’m having an issue displaying my nfts after calling them… I have previously used useMoralisQuery to call listed nfts in my moralis database which does not require an async function so I was able to create a map of the nfts and display them on a card component… (see example)

 const { data: listedNfts, isFetching: fetchingListedNfts } = useMoralisQuery(
          // TableName
          // Function for the query
          "ActiveItem",
          (query) => query.limit(10).descending("tokenId")
      )
      console.log(listedNfts)

listedNfts.map((nft) => {
                            console.log(nft.attributes)
                            const { price, nftAddress, tokenId, marketplaceAddress, seller } =
                                nft.attributes
return (
                                <div >
                                    <Card
                                        price={price}
                                        nftAddress={nftAddress}
                                        tokenId={tokenId}
                                        marketplaceAddress={marketplaceAddress}
                                        seller={seller}
                                        key={`${nftAddress}${tokenId}`}
                                    />
                                </div>
                            )
                        })
      

However - I am finding it difficult to do the same with fetchNFTs since it is an async function and so wrldhorse only exists within it… Does anyone have any direction regarding this?

const fetchNFTs = async () => {
  
    const options = {
      chain: "rinkeby",
      address: address,
    };
    
  const wrldhorse = await Moralis.Web3API.account.getNFTs(options);
  console.log(wrldhorse)
  
  }

you can return that data from that async function, you can use return wrldhorse at the end of the function

Not sure I follow - I need it to return within the container1Div

export default function test() {
  const {Web3Api} = useMoralisWeb3Api();
  const {isInitialized, Moralis, account,isWeb3Enabled} = useMoralis()
  
  
  const fetchNFTs = async () => {
  
    const options = {
      chain: "rinkeby",
      address: address,
    };
    
  const wrldhorse = await Moralis.Web3API.account.getNFTs(options);
  console.log(wrldhorse)

  return (
   
    <div className={styles.dashBoardDiv}>
    <Aside/>
    <div className={styles.frameDiv12}>
    <Header/>
    <div className={styles.bodyMain}>
    <div className={styles.container1Div}>
      
    
      </div>
    </div>
    </div>
    </div>

   
  );
  
  }

I don’t understand the question then.

I want to do the exact same thing I have done below however I cannot call wrldhorse outside of the async function fetchNFTs and therefore cannot create a map within the div that the nft needs to be displayed in as was done in the example below… How could I go about it so that it works as the example below does

const DashBoard = () => {
  
 
    const { isWeb3Enabled } = useMoralis()
      const { data: listedNfts, isFetching: fetchingListedNfts } = useMoralisQuery(
          // TableName
          // Function for the query
          "ActiveItem",
          (query) => query.limit(10).descending("tokenId")
      )
      console.log(listedNfts)
      
     

  

  return (
    <>
      <div className={styles.dashBoardDiv}>
      <Aside/>
        <div className={styles.frameDiv12}>
        <Header/>
          <main className={styles.bodyMain}>
            <div className={styles.container1Div}>
              <div className={styles.featureheaderDiv}>
                <div className={styles.featuredNFTsDiv}>Featured Listings</div>
                <div className={styles.frameDiv16}>
                  <div className={styles.frameDiv17}>
                    <div className={styles.cONNECTDiv}>Popular</div>
                    <img className={styles.icons3} alt="" src="icons3.svg" />
                  </div>
                  <div className={styles.frameDiv18}>
                    <img className={styles.icons3} alt="" src="icons4.svg" />
                  </div>
                  <div className={styles.frameDiv19}>
                    <img className={styles.icons3} alt="" src="icons5.svg" />
                  </div>
                </div>
              </div>
              <div className={styles.featuredDiv}>
            {isWeb3Enabled ? (
                    fetchingListedNfts ? (
                        <div
  style={{
    backgroundColor: '#ECECFE',
    borderRadius: '8px',
    padding: '20px'
  }}
>
  <Loading size={100} spinnerType="circle" />
</div>
                    ) : (
                        listedNfts.map((nft) => {
                            console.log(nft.attributes)
                            const { price, nftAddress, tokenId, marketplaceAddress, seller } =
                                nft.attributes
                            return (
                                <div >
                                    <Card
                                        price={price}
                                        nftAddress={nftAddress}
                                        tokenId={tokenId}
                                        marketplaceAddress={marketplaceAddress}
                                        seller={seller}
                                        key={`${nftAddress}${tokenId}`}
                                    />
                                </div>
                            )
                        })
                    )
                ) : (
                    <div><div
                    style={{
                      backgroundColor: '#ECECFE',
                      borderRadius: '20px',
                      padding: '30px',
                      width:'150%'
                      
                    }}
                  >
                    <Loading
                      size={50}
                      spinnerColor="#2E7DAF"
                      text="Enable Web3"
                      
                    />
                  </div></div>
                )}
              
            </div>
              
            </div>
          </main>
        </div>
      </div>
      
    </>
  );
};

export default DashBoard;

For new it looks like wrldhorse is a variable and not a function

Yes I understand that - my question is how do I get that data to exist within the container1Div?

You’ll need to push the result from the fetch into a state and render the nft cards based on that state. You can find a similar approach here

2 Likes

Thank you @qudusayo - this may be a dumb question but I get the error an element access expression should take an argument for the line const [nftBalances, setNftBalances] = useState<NFTBalance[] | undefined>([]);

Oh, the example there is in typescript, so you need to remove the types having such.

const [nftBalances, setNftBalances] = useState([]);
1 Like

This may be a dumb question but I’m not too familiar with ts so I do not know what exactly should change from your DisplayInput.tsx component… I know interface{} needs to go but not too sure what it must be replaced with if at all and nftMetadata.metadata! is bringing up an error as well

You can remove the types and try to remove things you think aren’t javascript related to making it look javascript at most. No need to replace anything. You can remove the ! at the end of nftMetadata.metadata!

1 Like

Do you mind filling me in on where I am going wrong with regard to logic… I get the error TypeError: Cannot read properties of undefined (reading 'token_address') @qudusayo

export default function test() {
  
  const [nftBalances, setNftBalances] = useState([]);
  const {Web3Api} = useMoralisWeb3Api();
  const {isInitialized, Moralis, account,isWeb3Enabled} = useMoralis()
  
  
  const fetchNFTs = async () => {
  
    const options = {
      chain: "rinkeby",
      address,
    };
    
  const wrldhorse = await Moralis.Web3API.account.getNFTs(options);
  
  let nftBalance = wrldhorse.result;
    console.log(nftBalance);
  
  await Promise.all(
    nftBalance.map(async (nft, index) => {
      // No Metadata, but token URI
      if (!!!nft.metadata && !!nft.token_uri) {
        
        try {
          const metadataReq = await axios.get(nft.token_uri);
          nft.metadata = JSON.stringify(metadataReq.data);
          
        } catch (error) {
          console.log(error);
        }
      } else {
        if (typeof nft.metadata === "object") {
          nft.metadata = JSON.stringify(nft.metadata);
          
        }
      }
    })
  );
  let filteredNFTs = nftBalance?.filter(
    (nftMetadata) =>
      nftMetadata.metadata !== null && nftMetadata.metadata !== "null"
  );
  setNftBalances(filteredNFTs);
};
  
  
  useEffect(() => {
    if (isInitialized) {
        fetchNFTs()
    }
}, [isInitialized])

  
  return (
    <div className={styles.dashBoardDiv}>
    <Aside/>
    <div className={styles.frameDiv12}>
    <Header/>
    <div className={styles.bodyMain}>
    <div className={styles.container1Div}>
    {isWeb3Enabled ? (
                    !nftBalances ? (
                        <div
  style={{
    backgroundColor: '#ECECFE',
    borderRadius: '8px',
    padding: '20px'
  }}
>
  <Loading size={100} spinnerType="circle" />
</div>
                    ) : (
                        nftBalances.map((nft) => {
                            console.log(nft.attributes)
                            const { token_address, token_id,contract_type, owner_of, block_number, block_number_minted, token_uri, metadata, synced_at, amount, name, symbol } =
                                nft.attributes
                            return (
                                <div >
                                    <Card
                                        
                                        token_address={token_address}
                                        token_id={token_id}
                                        owner_of={owner_of}
                                        
                                        key={`${token_address}${token_id}`}
                                    />
                                </div>
                            )
                        })
                    )
                ) : (
                    <div><div
                    style={{
                      backgroundColor: '#ECECFE',
                      borderRadius: '20px',
                      padding: '30px',
                      width:'150%'
                      
                    }}
                  >
                    <Loading
                      size={50}
                      spinnerColor="#2E7DAF"
                      text="Enable Web3"
                      
                    />
                  </div></div>
                )}
      </div>
    </div>
    </div>
    </div>

   
  );
}

when you see this type of error, you have to look in code where token_address is used, and see what happens there

1 Like

sorted thank you @cryptokid

1 Like