How to check if user has a specific token by querying NFTBalances

I am trying to check if a user has a specific token, in my case token_id should be “87”. How can I check that using NFTBalances?

I wrote the code below but it is not working.

import React, { useState , useEffect } from "react";

import { useMoralis, useNFTBalances } from "react-moralis";

function Club() {

    const { isInitialized } = useMoralis();

    const { data: NFTBalances } = useNFTBalances()

    const [isMember, setIsMember] = useState(false);

   

console.log(NFTBalances);

useEffect(() => {

  async function fetchData() {

 

  if (isInitialized) {

    const NFTs = NFTBalances.result;

    if (NFTBalances?.result) {

      for (let NFT of NFTs) {

            if(NFT.token_id=="87") {

               setIsMember(true);

             

            }

            else {

              setIsMember(false);

            }

             

      }

     

        }

 

  }

  fetchData();

}}, [isInitialized]);

  return (

    <div>

      {isMember?  <div className="notification is-success">Welcome! You are a premium member of our club!</div>:<div>You don't have access to this page.</div>}

      </div>

      )

                               

}

export default Club;

How can I fix it? It only shows that I don’t have the token but I actually do.

Maybe add a return statement here to stop the loop when token_id == "87".

1 Like

If you didn’t specify the chain here, it’ll be ETH by default. You can specify the chain such like const { data: NFTBalances } = useNFTBalances({ chain: "mumbai" });. You can get the chains Here

Here’s a little fix to the useEffect

useEffect(() => {
  function fetchData() {
    if (NFTBalances?.result) {
    const NFTs = NFTBalances.result;
      for (let NFT of NFTs) {
        if (NFT.token_id == "87") {
          setIsMember(true);
        } 
      }
    }
  }
  if (isInitialized) fetchData();
}, [isInitialized, NFTBalances]);

You need to remove this block because it’ll set is member back to false. You can also add the return statement to return setIsMember(true); to break out of the loop

2 Likes

Thanks a lot @qudusayo !
I tried what you suggested. It makes a lot of sense now but I am still not able to get the correct result on the page. I think the variable isMember is not receiving any value but I don’t know why.
Here is my updated code.

import React, { useState , useEffect } from "react";

import { useMoralis, useNFTBalances } from "react-moralis";

function Club() {

    const { isInitialized } = useMoralis();

    const { data: NFTBalances } = useNFTBalances()

    const [isMember, setIsMember] = useState(false);

 

useEffect(() => {

  async function fetchData() {

    if (NFTBalances?.result) {

      const NFTs = NFTBalances.result;

      for (let NFT of NFTs) {

            if(NFT.token_id===54) {

               return setIsMember(true);            

       }

      }

    }

 

  if (isInitialized) fetchData();

}}, [isInitialized, NFTBalances]);

  return (

    <div>

      {isMember?  <div className="notification is-success">Welcome! You are a premium member of our club!</div>:<div>You don't have access to this page.</div>}

      </div>

      )

                               

}

export default Club;

Am I missing anything on the return statement?
I am also getting this warning.

Line 11:18: 'fetchData' is defined but never used no-unused-vars

Do I need to declare this fetchData function on my return statement?

You have your if (isInitialized) fetchData(); inside fetchData, move it one level out in your useEffect.

1 Like

Thanks a lot @alex.
I have moved that chunk one level up and that has cleared the warning message.

useEffect(() => {

  async function fetchData() {

    if (NFTBalances?.result) {

      const NFTs = NFTBalances.result;

      for (let NFT of NFTs) {

            if(NFT.token_id===54) {

               return setIsMember(true);            

       }

      }

    }  

}

if (isInitialized) fetchData();

}, [isInitialized, NFTBalances]);

My isMember is still empty though. Do I need to change anything in the return statement?

Use if(NFT.token_id==="54"). token_id should be a string, so if you’re using === and a number, isNumber won’t be set to true.

1 Like

Here’s a fix to the hook

  useEffect(() => {
    async function fetchData() {
      if (NFTBalances?.result) {
        const NFTs = NFTBalances.result;

        for (let NFT of NFTs) {
          console.log(NFT.token_id);
          if (NFT.token_id === "7") {
            return setIsMember(true);
          }
        }
      }
    }
    if (isInitialized && isAuthenticated) fetchData();
  }, [isInitialized, NFTBalances, isAuthenticated]);

Where you have

  const { isInitialized, isAuthenticated } = useMoralis();

There’s a console.log in the effect, so you can check the logged tokenIds, and make sure you’re authenticated, so it’s gonna fetch nftBalances for the authenticated user

1 Like

Thanks guys! Based on @alex and @qudusayo’s comments, I managed to write the code below, which is working fine on development.

import React, { useState , useEffect } from "react";
import { useMoralis, useNFTBalances } from "react-moralis";
import CircularProgress from '@mui/material/CircularProgress';

function Club() {
    const { isInitialized, isAuthenticated} = useMoralis();
    const { data: NFTBalances } = useNFTBalances()
    const [isMember, setIsMember] = useState();
    const [memberImage, setMemberImage] = useState();
    console.log(NFTBalances)

useEffect(() => {
  async function fetchData() {
    if (NFTBalances?.result) {
      const NFTs = NFTBalances.result;
      for (let NFT of NFTs) {
            if(NFT.token_id==="87") {
               setIsMember(true);    
               setMemberImage(NFT.metadata?.image);        
               return;
       }
       if (isMember==null) setIsMember(false);
      }
    }  
}
if (isInitialized && isAuthenticated) fetchData();
}, [isInitialized, NFTBalances, isAuthenticated]);
  return (
    <div>
         {isMember==null ? (
               <CircularProgress color="secondary" />
            ) : (
             <br />
            )}
      {isMember?  <div className="notification is-success">Welcome! You are a premium member of our club!</div>:<div>You don't have access to this page.</div>}
        <div>
          {isMember?  <img src={memberImage} />:<span></span>}
        </div>
      </div>
      )                   
}

export default Club;

As I mentioned, the code above works 100% on development but it is not working on production. On production it only says that the user is not a member. I am still figuring out why this has a different outcome on production.

the user is not a member

Is this from an error or are you just saying the app isn’t displaying that the user is a member when it should be like in dev? Using the same login account? Check your console and deploy/build logs for any errors.

1 Like