[ethereum-nft-marketplace-boilerplate] does not fully work with latest version of [react-moralis 0.3.11] [SOLVED]

Hey,

I was using https://github.com/ethereum-boilerplate/ethereum-nft-marketplace-boilerplate

while following the YouTube tutorial: https://www.youtube.com/watch?v=WZWCzsB1xUE&ab_channel=MoralisWeb3

and after updating
"react-moralis": "^0.2.6", to "react-moralis": "^0.3.11",
I canā€™t list tokens of ERC1155 contract (NFT collections in marketplace)

meaning token.getAllTokenIds in version 0.2.6 returns data in version 0.3.11 does not return any data

It looks like in 0.2.6 the retries are performed and in the version 0.3.11 it is doing a single call

logs while using 0.3.11:

Screenshot 2021-12-25 at 21.44.18

logs while using 0.2.6

1 Like

editing my last post as I managed to fix this.

TLDR; itā€™s all about autoFetch option in useMoralisWeb3ApiCall hook
when I added { autoFetch: !!token && addr !== "explore" }, it started to work

the original code that did not work (nft details were not fetched):

export const useNFTTokenIds = (addr) => {
  const { token } = useMoralisWeb3Api();
  const { chainId } = useMoralisDapp();
  const { resolveLink } = useIPFS();
  const [NFTTokenIds, setNFTTokenIds] = useState([]);
  const [totalNFTs, setTotalNFTs] = useState();
  const [fetchSuccess, setFetchSuccess] = useState(true);
  const {
    fetch: getNFTTokenIds,
    data,
    error,
    isLoading,
  } = useMoralisWeb3ApiCall(token.getAllTokenIds, {
    chain: chainId,
    address: addr,
    limit: 10,
  });

  console.log('useNFTTokenIds', data)

  useEffect(async () => {
    console.log('useEffect useNFTTokenIds', data?.result)
    if (data?.result) {
      console.log('useEffect useNFTTokenIds | retrived data')
      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);
          }
        }
      }
      setNFTTokenIds(NFTs);
    }
  }, [data]);

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

new code that works

export const useNFTTokenIds = (addr, limit = 3) => {
    const { token } = useMoralisWeb3Api();
    const { chainId } = useMoralis();
    const { resolveLink } = useIPFS();
    const getAllTokenIdsOpts = {
        chain: chainId,
        address: addr,
        limit: limit,
    };

    const {
        fetch: getNFTTokenIds,
        data,
        error,
        isLoading,
        isFetching,
    } = useMoralisWeb3ApiCall(
        token.getAllTokenIds,
        getAllTokenIdsOpts,
        { autoFetch: !!token && addr !== "explore" },
    );

    const NFTTokenIds = useMemo(() => {
        console.log('fetching tokenIds data')
        if (!data?.result || !data?.result.length) {
            return data;
        }
        const formattedResult = data.result.map((nft) => {
            try {
                if (nft.metadata) {
                    const metadata = JSON.parse(nft.metadata);
                    const image = resolveLink(metadata?.image);
                    return { ...nft, image, metadata };
                }
            } catch (error) {
                return nft;
            }
            return nft;
        });

        return { ...data, result: formattedResult };
    }, [data]);

    return { getNFTTokenIds, data: NFTTokenIds, error, isLoading, isFetching };
};
1 Like

Feel free to submit PR to our public repo that will fix it!

We want the community to help us maintain it - thatā€™s why we open source boilerplates :raised_hands:

Thanks for helping!

1 Like

Thanks!

Will do that :slight_smile:

2 Likes

Would really appreciate that.
Iā€™m having a similar issue, I canā€™t list NFTs for sale.
Iā€™ve tried to use the code youā€™ve provided but I get a few errors like useMemo() is undefined.

My programming skills are pretty basic so Iā€™m just throwing possible solutions at the problem and will see if something works.
Cheers!

Just add

import { useMemo } from "react";
import { useMoralis } from "react-moralis";

it should work.

2 Likes

Thank you!

Iā€™m getting a new error:

Iā€™ve tried to change a few lines in NFTTokenIds.jsx and useNFTTokenIds.js to make it work but I canā€™t get rid of this new error.
I might be over my skis here but it seems like Iā€™m so close to getting this to work so I donā€™t want to quit.

Getting the same after updating moralis packages and trying this fix

Hey I created useNFTTokenIds hook for my project for the latest moralis version, I will maybe make a PR that will add it to react-moralis

that is the full useNFTTokenIds hook:

import { useMemo } from "react";
import { useMoralis } from "react-moralis";
import { useMoralisWeb3Api, useMoralisWeb3ApiCall } from "react-moralis";
import { useIPFS } from "./useIPFS";

export const useNFTTokenIds = (addr, limit = 3) => {
    const { token } = useMoralisWeb3Api();
    const { chainId } = useMoralis();
    const { resolveLink } = useIPFS();
    const getAllTokenIdsOpts = {
        chain: chainId,
        address: addr,
        limit: limit,
    };

    const {
        fetch: getNFTTokenIds,
        data,
        error,
        isLoading,
        isFetching,
    } = useMoralisWeb3ApiCall(
        token.getAllTokenIds,
        getAllTokenIdsOpts,
        { autoFetch: !!token && addr !== "explore" },
    );

    const NFTTokenIds = useMemo(() => {
        console.log('fetching tokenIds data')
        if (!data?.result || !data?.result.length) {
            return data;
        }
        const formattedResult = data.result.map((nft) => {
            try {
                if (nft.metadata) {
                    const metadata = JSON.parse(nft.metadata);
                    const image = resolveLink(metadata?.image);
                    return { ...nft, image, metadata };
                }
            } catch (error) {
                return nft;
            }
            return nft;
        });

        return { ...data, result: formattedResult };
    }, [data]);

    return { getNFTTokenIds, data: NFTTokenIds, error, isLoading, isFetching };
};

then use this hook like so:

import { useNFTTokenIds } from "hooks/useNFTTokenIds";

const { data: NFTTokenIds, error: NFTsFetchError } = useNFTTokenIds(nftAddress);
console.log("NFTTokenIds", NFTTokenIds);

It should work :slight_smile:

2 Likes

Thanks for this, Iā€™ll have to test it out :slight_smile:

1 Like

Just tested this, data is coming back and all appears to look well, thanks a lot! Great starting point to expand on further.

Happy new year in advance!

1 Like

Dose this still work?
I introduced it to the code and got a mountain of errors

What file does this get imported too and where

import { useNFTTokenIds } from ā€œhooks/useNFTTokenIdsā€;

const { data: NFTTokenIds, error: NFTsFetchError } = useNFTTokenIds(nftAddress);
console.log(ā€œNFTTokenIdsā€, NFTTokenIds);

Hi, when I follow your instructions, I get an error that nftAddress is not defined. Where would I declare this variable?

Thanks.

These contain invalid characters? How did you fix this?

What do you mean? Do you get an error? For the reference to the nftAddress variable, it will need to be defined in your own code or use your own address string or variable as the parameter.