Search code examples
javascriptreactjsnext.jsundefinedtypeerror

Unhandled Runtime Error while executing a JS code


On my Localhost:3000, when I am running the code, I am getting an error saying:

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'id')

For the Source part, it is showing a certain section of my code, which is:-

    ;(async () => {
  20 |     setSelectedMarketNft(
> 21 |       listings.find((marketNft) => marketNft.asset?.id === selectedNft.id)
     |                                                                       ^
  22 |     )
  23 |   })()
  24 | }, [selectedNft, listings, isListed])

There are certain questions of the similar type on stackOverflow, but I am unable to find any answers from any of them. I am making a web3 project, where I am using next.js, sanity and thirweb.

The source code that contains this is:-

 const MakeOffer = ({ isListed, selectedNft, listings, marketPlaceModule }) => {
  const [selectedMarketNft, setSelectedMarketNft] = useState()
  const [enableButton, setEnableButton] = useState(false)

  useEffect(() => {
    if (!listings || isListed === 'false') return
    ;(async () => {
      setSelectedMarketNft(
        listings.find((marketNft) => marketNft.asset?.id === selectedNft.id)
      )
    })()
  }, [selectedNft, listings, isListed])

  useEffect(() => {
    if (!selectedMarketNft || !selectedNft) return

    setEnableButton(true)
  }, [selectedMarketNft, selectedNft])

Link to the full source code of the file where this error is occuring is:- https://github.com/hemang-h/Standard-Demo-Marketplace-and-Minting/blob/main/components/nft/Purchase.js

Can anyone guide me what I am doing wrong here?

EXTRAS Just for a better understanding, this is the full source code of the file where I am facing this error:

import { useEffect, useState } from 'react'

import { HiTag } from 'react-icons/hi'
import { IoMdWallet } from 'react-icons/io'
import toast, { Toaster } from 'react-hot-toast'

const style = {
  button: `mr-8 flex items-center py-2 px-12 rounded-lg cursor-pointer`,
  buttonIcon: `text-xl`,
  buttonText: `ml-2 text-lg font-semibold`,
}

const MakeOffer = ({ isListed, selectedNft, listings, marketPlaceModule }) => {
  const [selectedMarketNft, setSelectedMarketNft] = useState()
  const [enableButton, setEnableButton] = useState(false)

  useEffect(() => {
    if (!listings || isListed === 'false') return
    ;(async () => {
      setSelectedMarketNft(
        listings.find((marketNft) => marketNft.asset?.id === selectedNft.id)
      )
    })()
  }, [selectedNft, listings, isListed])

  useEffect(() => {
    if (!selectedMarketNft || !selectedNft) return

    setEnableButton(true)
  }, [selectedMarketNft, selectedNft])

  const confirmPurchase = (toastHandler = toast) =>
    toastHandler.success(`Purchase successful!`, {
      style: {
        background: '#04111d',
        color: '#fff',
      },
    })

  const buyItem = async (
    listingId = selectedMarketNft.id,
    quantityDesired = 1,
    module = marketPlaceModule
  ) => {
    console.log(listingId, quantityDesired, module, 'david')
    // yo RAZA lets goooo!!!
    //yo Qazi, ok
    // sure okay about to run it...
    // just clicked buy now...
    // still error
    // where can i see the contract address of the marketplace module
    // in [nftId.js]
    await module
      .buyoutDirectListing({
        listingId: listingId,
        quantityDesired: quantityDesired,
      })
      .catch((error) => console.error(error))

    confirmPurchase()
  }

  return (
    <div className="flex h-20 w-full items-center rounded-lg border border-[#151c22] bg-[#303339] px-12">
      <Toaster position="bottom-left" reverseOrder={false} />
      {isListed === 'true' ? (
        <>
          <div
            onClick={() => {
              enableButton ? buyItem(selectedMarketNft.id, 1) : null
            }}
            className={`${style.button} bg-[#2081e2] hover:bg-[#42a0ff]`}
          >
            <IoMdWallet className={style.buttonIcon} />
            <div className={style.buttonText}>Buy Now</div>
          </div>
          <div
            className={`${style.button} border border-[#151c22]  bg-[#363840] hover:bg-[#4c505c]`}
          >
            <HiTag className={style.buttonIcon} />
            <div className={style.buttonText}>Make Offer</div>
          </div>
        </>
      ) : (
        <div className={`${style.button} bg-[#2081e2] hover:bg-[#42a0ff]`}>
          <IoMdWallet className={style.buttonIcon} />
          <div className={style.buttonText}>List Item</div>
        </div>
      )}
    </div>
  )
}

export default MakeOffer

Solution

  • The error is solved, turns out that I just had to add

    if(!selectedNft) return;
    

    to successfully run my code. Final code will be as:

    import { useEffect, useState } from 'react'
    
    import { HiTag } from 'react-icons/hi'
    import { IoMdWallet } from 'react-icons/io'
    import toast, { Toaster } from 'react-hot-toast'
    
    const style = {
      button: `mr-8 flex items-center py-2 px-12 rounded-lg cursor-pointer`,
      buttonIcon: `text-xl`,
      buttonText: `ml-2 text-lg font-semibold`,
    }
    
    const MakeOffer = ({ isListed, selectedNft, listings, marketPlaceModule }) => {
      const [selectedMarketNft, setSelectedMarketNft] = useState()
      const [enableButton, setEnableButton] = useState(false)
    
      useEffect(() => {
        if(!selectedNft) return;
        if (!listings || isListed === 'false') return
        ;(async () => {
          setSelectedMarketNft(
            listings.find((marketNft) => marketNft.asset?.id === selectedNft.id)
          )
        })()
      }, [selectedNft, listings, isListed])
    
      useEffect(() => {
        if (!selectedMarketNft || !selectedNft) return
    
        setEnableButton(true)
      }, [selectedMarketNft, selectedNft])
    
      const confirmPurchase = (toastHandler = toast) =>
        toastHandler.success(`Purchase successful!`, {
          style: {
            background: '#04111d',
            color: '#fff',
          },
        })
    
      const buyItem = async (
        listingId = selectedMarketNft.id,
        quantityDesired = 1,
        module = marketPlaceModule
      ) => {
        console.log(listingId, quantityDesired, module, 'david')
        // yo RAZA lets goooo!!!
        //yo Qazi, ok
        // sure okay about to run it...
        // just clicked buy now...
        // still error
        // where can i see the contract address of the marketplace module
        // in [nftId.js]
        await module
          .buyoutDirectListing({
            listingId: listingId,
            quantityDesired: quantityDesired,
          })
          .catch((error) => console.error(error))
    
        confirmPurchase()
      }
    
      return (
        <div className="flex h-20 w-full items-center rounded-lg border border-[#151c22] bg-[#303339] px-12">
          <Toaster position="bottom-left" reverseOrder={false} />
          {isListed === 'true' ? (
            <>
              <div
                onClick={() => {
                  enableButton ? buyItem(selectedMarketNft.id, 1) : null
                }}
                className={`${style.button} bg-[#2081e2] hover:bg-[#42a0ff]`}
              >
                <IoMdWallet className={style.buttonIcon} />
                <div className={style.buttonText}>Buy Now</div>
              </div>
              <div
                className={`${style.button} border border-[#151c22]  bg-[#363840] hover:bg-[#4c505c]`}
              >
                <HiTag className={style.buttonIcon} />
                <div className={style.buttonText}>Make Offer</div>
              </div>
            </>
          ) : (
            <div className={`${style.button} bg-[#2081e2] hover:bg-[#42a0ff]`}>
              <IoMdWallet className={style.buttonIcon} />
              <div className={style.buttonText}>List Item</div>
            </div>
          )}
        </div>
      )
    }
    
    export default MakeOffer