2

My website works fine locally but when deployed to Vercel, I get a client-side exception error. After checking other parts of the website, I've found the culprit to be in my UMI function code. I'm getting an error of:

TypeError: Cannot read properties of undefined (reading 'length')

That I think might be coming from:

(candyMachine.itemsRedeemed === 500 as BigIntInput)

Not sure if that has to do with how the candymachine is fetched or if I'm using the BigIntInput wrong and need a different way to read if items redeemed is less than 500?

Here is my full code for the page. Like I mentioned earlier it will work fine on the local level. It's just not working in production.

import {
  some,
  generateSigner,
  transactionBuilder,
  publicKey,
  BigIntInput
} from "@metaplex-foundation/umi";
import {
  CandyMachine,
  fetchCandyMachine,
  mintV2
} from "@metaplex-foundation/mpl-candy-machine";
import { TokenStandard } from "@metaplex-foundation/mpl-token-metadata";
import { setComputeUnitLimit } from "@metaplex-foundation/mpl-toolbox";
import { CircularProgress, Container, } from "@mui/material";
import Button from "@mui/material/Button";
import Grid from "@mui/material/Grid";
import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography";
import { useWallet } from "@solana/wallet-adapter-react";
import { useEffect, useState } from "react";
import styles from '../../styles/mint.module.css';
import { useSnackbar } from "notistack";
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
import { mplCandyMachine } from "@metaplex-foundation/mpl-candy-machine";
import { walletAdapterIdentity } from '@metaplex-foundation/umi-signer-wallet-adapters';
import { WalletMultiButton } from "@solana/wallet-adapter-react-ui";


const CarMint = () => {
  const wallet = useWallet();
  const [pageLoading, setPageLoading] = useState<boolean>(true);
  const [candyMachine, setCandyMachine] = useState<CandyMachine | undefined>();
  const [isUserMinting, setIsUserMinting] = useState(false);
  const owner = publicKey(process.env.NEXT_PUBLIC_OWNER_WALLET as unknown as string);
  const { enqueueSnackbar } = useSnackbar();
  const umi = createUmi(process.env.NEXT_PUBLIC_SOLANA_RPC_HOST as unknown as string)
  .use(walletAdapterIdentity(wallet))
  .use(mplCandyMachine());

  const getCandyMachine = async () => {
    setPageLoading(true);
    try {
      const cmPubkey = publicKey(process.env.NEXT_PUBLIC_CANDY_MACHINE_CAR_ID as unknown as string);
      const candyMachine = await fetchCandyMachine(umi, cmPubkey);
      if (!candyMachine) throw new Error("No Candymachine at address");
      setCandyMachine(candyMachine);
    } catch (error) {
      console.log("Fetching CM Error", error);
      enqueueSnackbar(
        "Fetching CM Error: Check console logs for more details",
        {
          variant: "error",
          anchorOrigin: { vertical: "top", horizontal: "right" },
        }
      );
    }
  
    setPageLoading(false);
  };
  
  useEffect(() => {
    getCandyMachine();
  }, []);



  const getPayMintButtonContent = () => {
    if (!candyMachine) {
      return "Loading...";
    }

    if (isUserMinting) {
      return "Minting in progress..";
    } else if (candyMachine.itemsRedeemed === 500 as BigIntInput) {
      return "Sold out";
    } else {
      return <img
      style={{
        maxHeight: "75px",
      }}
      src="/images/freeby.png"
      alt="freeby"
    />;
    }
  };

  const payMintButtonClicked = async () => {
    setIsUserMinting(true);
    try {
      if (candyMachine?.publicKey) {
        const nftMint = generateSigner(umi);
    const freeMint = await transactionBuilder()
      .add(setComputeUnitLimit(umi, { units: 800_000 }))
      .add(
        mintV2(umi, {
          candyMachine: candyMachine.publicKey,
          nftMint,
          collectionMint: candyMachine.collectionMint,
          collectionUpdateAuthority: owner,
          group: some("fren"),
          mintArgs: {
            mintLimit: some({ id: 1 }),
            solPayment: some({ destination: owner }),
          },
          tokenStandard: TokenStandard.ProgrammableNonFungible,
        })
      )
      .sendAndConfirm(umi);
    
      console.log( "Mint Success!!!", freeMint )
      enqueueSnackbar(
        "Mint Success!!!",
        {
          variant: "success",
          anchorOrigin: { vertical: "top", horizontal: "right" },
        }
      );
      getCandyMachine();
      }
    } catch (error) {
      console.error("Mint Error", error);
      enqueueSnackbar("Mint Error: Only one per customer, Pal!!!", {
        variant: "error",
        anchorOrigin: { vertical: "top", horizontal: "right" },
      });
    }
    setIsUserMinting(false);
  };



  return (
    <Container style={{ marginTop: 20 }}>
    <Container maxWidth="xs" style={{ position: 'relative' }}> 
      <Paper
          style={{ padding: 24, background: '#3a434a', borderColor: '#ffd839', border: '3px solid #ffd839', borderRadius: 6 }}
        >
          {!wallet.connected ? (
              <div className={styles.connectButton}>
              <WalletMultiButton className="w-80 text-center mx-3">
              <img className="mt-10" src="/images/freeby.png"></img>
              </WalletMultiButton>
            </div>
          ) : (
            <>
              <Grid
                container
                direction="row"
                justifyContent="center"
                wrap="nowrap"
              >
                {pageLoading ? (
            <CircularProgress />
            ) : (
                <Grid item xs={3}>
                  <Typography variant="h6" color="#ffd839" style={{
                      textAlign: "center", fontFamily: "Press Start 2P"
                    }}>
                    Redeemed
                  </Typography>
                  <Typography
                    variant="h6"
                    color="white"
                    style={{
                      fontWeight: "bold",
                      textAlign: "center",
                    }}
                  >
                    {`${candyMachine ? candyMachine.itemsRedeemed : "Loading.."}`}
                  </Typography>
                </Grid>
                )}
                <Grid item xs={4}>
                    <Typography 
                      variant="h6" 
                      color="#ffd839"
                      style={{ fontFamily: "Press Start 2p" }}
                      >
                        .
                    </Typography>
                    <Typography
                      variant="h6"
                      color="white"
                      style={{ fontFamily: "Press Start 2P" }}
                    >
                      /500
                    </Typography>
                  </Grid>
                <Grid item xs={4}>
                    <Typography 
                      variant="h6" 
                      color="#ffd839"
                      style={{ fontFamily: "Press Start 2p" }}
                      >
                        Price USDC
                    </Typography>
                    <Typography
                      variant="h6"
                      color="white"
                      style={{ fontFamily: "Press Start 2P" }}
                    >
                      Free Fiddy
                    </Typography>
                  </Grid>
              </Grid>
              <Grid
                container
                direction="row"
                justifyContent="center"
                wrap="nowrap"
              >
                <div className={styles.mintButton}>
                <Button onClick={async () => await payMintButtonClicked()} disabled={isUserMinting || candyMachine?.itemsRedeemed === 500 as BigIntInput}>
                  <Typography variant="body2" color="textSecondary" style={{
                      fontSize: "16px",
                      fontWeight: "bold",
                      color: "white",
                      textAlign: "center",
                    }}>
                    { getPayMintButtonContent() }
                  </Typography>
                </Button>
                </div>
              </Grid>
            </>
          )}
        </Paper>
      </Container>
    </Container>
  );
};

export default CarMint;

1 Answer 1

1

When fetching a candy machine account, the type of candyMachine.itemsRedeemed will always be a bigint. Therefore:

(candyMachine.itemsRedeemed === 500 as BigIntInput)

is strictly comparing a number with a bigint and should always be false. You want'll to use this instead:

(candyMachine.itemsRedeemed === BigInt(500))

Perhaps this wrong condition is causing your code to wrongly access the length of an array somewhere. That being, said I'm not sure why this condition would pass locally.

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.