NFT Marketplace Item Details

I am trying to do, that when i press on the img of the item on the marketplace that a modal opens with more information about this nft. And it works, but only 1 time and then it always shows the same Item Details even when i press on another item. I have to refresh only than it works again.

renderItem = (item) => {
    const itemForSale = marketplaceItemTemplate.cloneNode(true);
    if (item.sellerAvatar){
        itemForSale.getElementsByTagName("img")[0].src = item.sellerAvatar.url();
        itemForSale.getElementsByTagName("p")[0].innerText = item.sellerUsername;
    }

    itemForSale.getElementsByTagName("input")[0].src = item.image;
    itemForSale.getElementsByTagName("h5")[0].innerText = item.name;
    itemForSale.getElementsByTagName("p")[1].innerText = item.description;
    itemForSale.getElementsByTagName("input")[0].onclick = () => renderItemDetails(item);

    itemForSale.getElementsByTagName("button")[0].innerText = `Buy for ${item.askingPrice}`;
    itemForSale.getElementsByTagName("button")[0].onclick = () => buyItem(item);
    itemForSale.id = `item-${item.uid}`;
    itemsForSale.appendChild(itemForSale);
}

renderItemDetails = (item) => {
    $("#itemModal").modal("show");
    const itemTemplate = initTemplate("itemTemplate");

    const itemDetail = itemTemplate.cloneNode(true);
    itemDetail.getElementsByTagName("img")[0].src = item.image;
    itemDetail.getElementsByTagName("h5")[0].innerText = item.name;
    itemDetail.getElementsByTagName("p")[0].innerText = item.description;

    itemDetail.getElementsByTagName("button")[0].innerText = `Buy for ${item.askingPrice}`;
    itemDetail.getElementsByTagName("button")[0].onclick = () => buyItem(item);

    itemDetail.id = `item-${item.uid}`;
    itemDetails.appendChild(itemDetail);
}

Hi @Manuel138

It’s hard to test or add any edits to the code since you posted a small part of it.

Ok this is my main.js

Moralis.initialize("YD9aYXgNHsHa4ia8gRrC75mGKIQpFNtwg5gJasCZ");
Moralis.serverURL = 'https://ynetmdkm7kum.grandmoralis.com:2053/server'
const TOKEN_CONTRACT_ADDRESS = "0x18908aFF1889B8fC9eBF7e92E48dC42A9D0D8e22";
const MARKETPLACE_CONTRACT_ADDRESS = "0xC0cD43Aa5907d6926b4B221b4F98d1ff00130d04";

init = async () => {
    window.web3 = await Moralis.enableWeb3();
    window.tokenContract = new web3.eth.Contract(tokenContractAbi, TOKEN_CONTRACT_ADDRESS);
    window.marketplaceContract = new web3.eth.Contract(marketplaceContractAbi, MARKETPLACE_CONTRACT_ADDRESS);
    initUser();
    loadItems();

    const soldItemsQuery = new Moralis.Query('SoldItems');
    const soldItemsSubscription = await soldItemsQuery.subscribe();
    soldItemsSubscription.on("create", onItemSold);

    const itemsAddedQuery = new Moralis.Query('ItemsForSale');
    const itemsAddedSubscription = await itemsAddedQuery.subscribe();
    itemsAddedSubscription.on("create", onItemAdded);
}

onItemSold = async (item) => {
    const listing = document.getElementById(`item-${item.attributes.uid}`);
    if (listing){
        listing.parentNode.removeChild(listing);
    }
    
    user = await Moralis.User.current();
    if (user){
        const params = {uid: `${item.attributes.uid}`};
        const soldItem = await Moralis.Cloud.run('getItem', params);
        if (soldItem){
            if (user.get('accounts').includes(item.attributes.buyer)){
                getAndRenderItemData(soldItem, renderUserItem);
            }

            const userItemListing = document.getElementById(`user-item-${item.tokenObjectId}`);
            if (userItemListing) userItemListing.parentNode.removeChild(userItemListing);
          
        }
   
    }
}

onItemAdded = async (item) => {
    const params = {uid: `${item.attributes.uid}`};
    const addedItem = await Moralis.Cloud.run('getItem', params);
    if (addedItem){
        user = await Moralis.User.current();
        if (user){
            if (user.get('accounts').includes(addedItem.ownerOf)){
                const userItemListing = document.getElementById(`user-item-${item.tokenObjectId}`);
                if (userItemListing) userItemListing.parentNode.removeChild(userItemListing);

                getAndRenderItemData(addedItem, renderUserItem);
                return;
            }
        }
        getAndRenderItemData(addedItem, renderItem);
    }

}

initUser = async () => {
    if (await Moralis.User.current()){
        hideElement(userConnectButton);
        showElement(userProfileButton);
        showElement(openCreateItemButton);
        showElement(openMyNFTsItemButton);

    }else{
        showElement(userConnectButton);
        hideElement(userProfileButton);
        hideElement(openCreateItemButton);
        hideElement(openMyNFTsItemButton);
    }
}

login = async () => {
    try {
        await Moralis.Web3.authenticate();
        initUser();
    } catch (error) {
        alert(error)
    }
    location.reload();

}

logout = async () => {
    await Moralis.User.logOut();
    window.location.href = "index.html";
}

loadItems = async () => {
    const items = await Moralis.Cloud.run("getItems");
    user = await Moralis.User.current();
    items.forEach(item => {
        if (user){
            if (user.attributes.accounts.includes(item.ownerOf)){
                const userItemListing = document.getElementById(`user-item-${item.tokenObjectId}`);
                if (userItemListing) userItemListing.parentNode.removeChild(userItemListing);
                getAndRenderItemData(item, renderUserItem);
                return;
            }
        }
        getAndRenderItemData(item, renderItem);
    });
}

initTemplate = (id) => {
    const template = document.getElementById(id);
    template.id = "";
    template.parentNode.removeChild(template);
    return template;
}

renderUserItem = async (item) => {
    const userItemListing = document.getElementById(`user-item-${item.tokenObjectId}`);
    if (userItemListing) return;

    const userItem = userItemTemplate.cloneNode(true);
    userItem.getElementsByTagName("img")[0].src = item.image;
    userItem.getElementsByTagName("img")[0].alt = item.name;
    userItem.getElementsByTagName("h5")[0].innerText = item.name;

    userItem.getElementsByTagName("input")[0].value = item.askingPrice ?? 1;
    userItem.getElementsByTagName("input")[0].disabled = item.askingPrice > 0;
    userItem.getElementsByTagName("button")[0].disabled = item.askingPrice > 0;
    userItem.getElementsByTagName("button")[0].onclick = async () => {
        user = await Moralis.User.current();
        if (!user){
            login();
            return;
        }
        await ensureMarketplaceIsApproved(item.tokenId, item.tokenAddress);
        await marketplaceContract.methods.addItemToMarket(item.tokenId, item.tokenAddress, userItem.getElementsByTagName("input")[0].value).send({from: user.get('ethAddress') });
    };

    userItem.id = `user-item-${item.tokenObjectId}`
    userItems.appendChild(userItem);
}

renderItem = (item) => {
    const itemForSale = marketplaceItemTemplate.cloneNode(true);
    if (item.sellerAvatar){
        itemForSale.getElementsByTagName("img")[0].src = item.sellerAvatar.url();
        itemForSale.getElementsByTagName("p")[0].innerText = item.sellerUsername;
    }

    itemForSale.getElementsByTagName("input")[0].src = item.image;
    itemForSale.getElementsByTagName("h5")[0].innerText = item.name;
    itemForSale.getElementsByTagName("input")[0].onclick = () => renderItemDetails(item);

    itemForSale.getElementsByTagName("button")[0].innerText = `Buy for ${item.askingPrice}`;
    itemForSale.getElementsByTagName("button")[0].onclick = () => buyItem(item);
    itemForSale.id = `item-${item.uid}`;
    itemsForSale.appendChild(itemForSale);
}

renderItemDetails = (item) => {
    console.log(item);
    $("#itemModal").modal("show");
    const itemTemplate = initTemplate("itemTemplate");

    const itemDetail = itemTemplate.cloneNode(true);
    itemDetail.getElementsByTagName("img")[0].src = item.image;
    itemDetail.getElementsByTagName("h5")[0].innerText = item.name;
    itemDetail.getElementsByTagName("p")[0].innerText = item.description;

    itemDetail.getElementsByTagName("button")[0].innerText = `Buy for ${item.askingPrice}`;
    itemDetail.getElementsByTagName("button")[0].onclick = () => buyItem(item);

    itemDetail.id = `item-${item.uid}`;
    itemDetails.appendChild(itemDetail);
}

getAndRenderItemData = (item, renderFunction) => {
    
    fetch(item.tokenUri)
    .then(response => response.json())
    .then(data => {
        item.name = data.name;
        item.description = data.description;
        item.image = data.image;
        renderFunction(item);
    })
}

ensureMarketplaceIsApproved = async (tokenId, tokenAddress) => {
    user = await Moralis.User.current();
    const userAddress = user.get('ethAddress');
    const contract = new web3.eth.Contract(tokenContractAbi, tokenAddress);
    const approvedAddress = await contract.methods.getApproved(tokenId).call({from: userAddress});
    if (approvedAddress != MARKETPLACE_CONTRACT_ADDRESS){
        await contract.methods.approve(MARKETPLACE_CONTRACT_ADDRESS,tokenId).send({from: userAddress});
    }
}

buyItem = async (item) => {
    user = await Moralis.User.current();
    if (!user){
        login();
        return;
    } 
    
    await marketplaceContract.methods.buyItem(item.uid).send({from: user.get('ethAddress'), value: item.askingPrice});
    
}

hideElement = (element) => element.style.display = "none";
showElement = (element) => element.style.display = "block";


const userConnectButton = document.getElementById("btnConnect");
userConnectButton.onclick = login;

const userProfileButton = document.getElementById("btnUserInfo");

const openMyNFTsItemButton = document.getElementById("btnMyItems");

const openCreateItemButton = document.getElementById("btnOpenCreateItem");

document.getElementById("btnLogout").onclick = logout;

const userItems = document.getElementById("userItemsList");
const itemDetails = document.getElementById("itemDetailList");

const userItemTemplate = initTemplate("itemTemplate");
const marketplaceItemTemplate = initTemplate("marketplaceItemTemplate");

// Items for sale
const itemsForSale = document.getElementById("itemsForSale");

init();
1 Like

Does console.log(item); show the previous item in renderItemDetails ?

Yes, this works but just once. If i then press on another marketplace item the modal showing the first item pops up.

Screenshot 2021-11-23 171820
I get this error when i press the image button again.

Ok the error was because i did the initTemplate in the renderItemDetails function. But now i have the problem that when i press again on another item it doesn’t replace the previous item information it just goes below it.
like this: