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