0

I'm able to fetch and log the NFTs fetched from a connected wallet but having trouble figuring out how to render the data to display the images and nft info. Everything I tried comes up blank. Here is my page followed by my current card setup.

import { NextPage } from "next";
import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { Metaplex, walletAdapterIdentity, FindNftsByOwnerOutput, Metadata, JsonMetadata } from "@metaplex-foundation/js";
import { FC, useEffect, useState } from "react";
import { MediaRenderer } from "@thirdweb-dev/react";
import Container from "../components/Container/Container";
import NFT from "../components/NFT/OPENNFTCard"

export const BagGrabber: FC = () => {
  const [nftData, setNftData] = useState<JsonMetadata[]>()
  const [selectedNft, setSelectedNft] = useState<Metadata>();
  const { connection } = useConnection();
  const wallet = useWallet();
  const metaplex = Metaplex.make(connection).use(walletAdapterIdentity(wallet));

  // fetch nfts
  const fetchNfts = async () => {
    if (!wallet.connected) {
      return
    }

    // fetch NFTs for connected wallet
    const NFTs = await metaplex.nfts().findAllByOwner({
      owner: metaplex.identity().publicKey
  });

     // fetch off chain metadata for each NFT
     let counter: number = NFTs.length;
     console.log("counter: "+counter);

    let nftData = [] as unknown as JsonMetadata[];
    let counterI= 0;
    for (var i in NFTs){
    console.log(NFTs[i].uri);
    counterI+=1;
      let fetchResult = await fetch(NFTs[i].uri)
      let json = await fetchResult.json()
      nftData.push(json)
    }

    // set state
    setNftData(nftData);
    console.log(nftData);
  }

  // fetch nfts when connected wallet changes
  useEffect(() => {
    fetchNfts()
  }, [wallet])

  
  if (!nftData)
  return (
    <div className={"flex h-screen w-screen items-center justify-center"}>
      Loading ...
    </div>
  );

return (
  <>
  <Head>
    <title>{siteMetadata.siteName} | Big Bag</title>
  </Head>
  <div className="">  
  <Container maxWidth="lg">
    <h1 className="text-3xl font-bold">Your Big Bag of Ethereum Collectibles</h1>
    <div className={"flex items-center space-x-1"}>
        <p className={"w-1/4"}>TOTAL NFTs TO SELL:</p>
        </div>
        <div className={"flex items-center space-x-1"}>
        <p className={"w-1/4 text-green-400"}>{nftData.length}</p>
        </div>
    <h1>Drop some bags</h1>
    {nftData?.length === 0 ? (
        <div>No NFTs were found...</div>
      ) : (
        <div className={`nft-grid`}>
          {nftData?.map((nft: JsonMetadata, index: number) => {
            return (
              <NFT
                key={index}
                nft={{nft}}
              />
            );
          })}
        </div>
      )}
  </Container>
  </div>
  </>
);
}
);
}

NFT card

import { MediaRenderer, ThirdwebNftMedia } from "@thirdweb-dev/react";
import React from "react";
import styles from "./OPENNFT.module.css";
import { Metadata, FindNftsByOwnerOutput, JsonMetadata } from "@metaplex-foundation/js";

type Props = {
    nft: JsonMetadata;
  };
  
  export default function NFTComponent({ nft }: Props) {

    return (
        <>
        <div className={styles.nftContainer}>
          <MediaRenderer src={nft.image} className={styles.nftImage} />
    
          <p className={styles.nftTokenId}>{nft.name}</p>
          <p className={styles.nftTokenId}>Token ID #{nft.symbol}</p>
    
          <div className={styles.priceContainer}>
          
            {nft && (
              <div className={styles.nftPriceContainer}>
                <div>
                  <p className={styles.nftPriceLabel}>Contract:</p>
                  <p className={styles.nftPriceValue}>
                    {nft.collection?.family}
                  </p>
                </div>
              </div>
            )}
          </div>
          </div>
        </>
      );
    }

3 Answers 3

1

We have a complete guide on how you can fetch owned NFTs.

https://blog.thirdweb.com/guides/deploy-an-nft-collection-gallery-with-thirdweb/

You don't need to use the metaplex.nfts method at all. You can use the useNFTs hook and pass in the program from the address passed in. This should work.

1
  • It seems that way will only show nfts from one collection. I'm wanting it to showcase all nfts from the wallet. I do plan to this method to do a per collection showcase. May 8, 2023 at 16:42
0

The problem is that you are trying to assign the value of local variable nftData which has an any[] type to state variable of nftData which has a type of <JsonMetadata | undefined> .this is what is giving error. You can either give your local nftData the same type as the state variable or you can try converting everything into strings.

const [nftData, setNftData] = useState<string>("");
let nftData: string[] = [];
for (let i = 0; i < NFTs.length; i++) {
  let fetchResult = await fetch(NFTs[i].uri)
  let json = await fetchResult.json()
  let jsonString = JSON.stringify(json );
  nftData.push(jsonString )
}
 // set state
setNftData(nftData)

later on while using this you can again convert to JSON using JSON.parse(jsonString)

11
  • Thanks. Got it logging the metadata and set in state but still not rendering images or info in the return. I updated the way I ended up fetching the data. Do you have a way you would render? May 8, 2023 at 16:40
  • Ok..can u plz try logging the nft which u have passed as props and confirm that it is actually getting passed? Also are you getting any error or some extra info from the console ? May 9, 2023 at 10:33
  • No errors. In the console, it gives the count: 6 (I have six nfts in the test wallet), then it lists the 6 uri links for the .json files. It also original array of 6 FindNftsByOwnerOutput that it parses the uri links from. I can console log any individual pieces of information from the metadata json such as image, name, description etc. How can I console log the props? May 9, 2023 at 16:33
  • I can build out an individual card by manually inputting the counter number, say nftData[1].symbol or nftData[1].image and render a card but my issue is with nftData.map not working. May 9, 2023 at 18:50
  • In ur NFT card component try adding the console.log(nft) and check in the console if the nfts are actually passing to the card component. Also can u plz check the code in the container component because all your nfts will be rendered inside this container component? May 9, 2023 at 21:03
0

here is the completed working code. Thank you for all the help community.

import { NextPage } from "next";
import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { Metaplex, walletAdapterIdentity, FindNftsByOwnerOutput, Metadata, JsonMetadata } from "@metaplex-foundation/js";
import { FC, useEffect, useState } from "react";
import { MediaRenderer } from "@thirdweb-dev/react";
import Container from "../components/Container/Container";
import NFT from "../components/NFT/OPENNFTCard"

export const BagGrabber: FC = () => {
  const [nftData, setNftData] = useState<JsonMetadata[]>()
  const [selectedNft, setSelectedNft] = useState<Metadata>();
  const { connection } = useConnection();
  const wallet = useWallet();
  const metaplex = Metaplex.make(connection).use(walletAdapterIdentity(wallet));

  // fetch nfts
  const fetchNfts = async () => {
    if (!wallet.connected) {
      return
    }

    // fetch NFTs for connected wallet
    const NFTs = await metaplex.nfts().findAllByOwner({
      owner: metaplex.identity().publicKey
  });

     // fetch off chain metadata for each NFT
     let counter: number = NFTs.length;
     console.log("counter: "+counter);

    let nftData = [] as unknown as JsonMetadata[];
    let counterI= 0;
    for (var i in NFTs){
    console.log(NFTs[i].uri);
    counterI+=1;
      let fetchResult = await fetch(NFTs[i].uri)
      let json = await fetchResult.json()
      nftData.push(json)
    }

    // set state
    setNftData(nftData);
    console.log(nftData);
  }

  // fetch nfts when connected wallet changes
  useEffect(() => {
    fetchNfts()
  }, [wallet])

  
  if (!nftData)
  return (
    <div className={"flex h-screen w-screen items-center justify-center"}>
      Loading ...
    </div>
  );

return (
  <>
  <Head>
    <title>{siteMetadata.siteName} | Big Bag</title>
  </Head>
  <div className="">  
  <Container maxWidth="lg">
    <h1 className="text-3xl font-bold">Your Big Bag of Ethereum Collectibles</h1>
    <div className={"flex items-center space-x-1"}>
        <p className={"w-1/4"}>TOTAL NFTs TO SELL:</p>
        </div>
        <div className={"flex items-center space-x-1"}>
        <p className={"w-1/4 text-green-400"}>{nftData.length}</p>
        </div>
    <h1>Drop some bags</h1>
    {nftData?.length === 0 ? (
        <div>No NFTs were found...</div>
      ) : (
        <div className={`nft-grid`}>
          {nftData?.map((nft: JsonMetadata, index: number) => {
            return (
              <NFT
                key={index}
                nft={nft}
              />
            );
          })}
        </div>
      )}
  </Container>
  </div>
  </>
);
}
);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.