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
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.