SOLVED: Youtube tutorial - Rarible clone (Morarable) "I CLONED RARIBLE IN 24H" - 'item.uid' is undefined

hi, I have a problem when buying an nft ( part 14).

here is my code:

renderItem = (item) => {
        const itemForSale = marketplaceItemTemplate.cloneNode(true);

        if(item.sellerAvatar) {
            itemForSale.getElementsByTagName("img")[0].src = item.sellerAvatar.url();
            itemForSale.getElementsByTagName("img")[0].alt = item.sellerUsername;
            itemForSale.getElementsByTagName("h6")[0].innerText = item.sellerUsername;
        }
        itemForSale.getElementsByTagName("img")[1].src = item.image;
        itemForSale.getElementsByTagName("img")[1].alt = item.name;
        itemForSale.getElementsByTagName("h5")[0].innerText = item.name;
        itemForSale.getElementsByTagName("p")[0].innerText = item.description;

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

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});

}

here is the error I got in my console when clicking the buy button

index.js:223 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘length’)
at h.formatParam (index.js:223)
at index.js:99
at Array.map ()
at h.encodeParameters (index.js:93)
at index.js:438
at Array.map ()
at Object.b._encodeMethodABI (index.js:437)
at Object.b._processExecuteArguments (index.js:700)
at Object.b._executeMethod (index.js:719)
at buyItem (main.js:380)

please help))

what is in that item.uid that you sent as parameter?
can you use a console.log to print it before calling that smart contract function?

nope,

item.uid

VM702:1 Uncaught ReferenceError: item is not defined
at :1:1

do you have any ideas where to check this item.uid and why it’s undefined?

I don’t know that, you can look on what you have in that item object, maybe you have something else similar to that uuid.

ok so this is the item

// Creating new class
        const Item = Moralis.Object.extend("Item");

        // Create a new instance of that class. 
        const item = new Item();

        // Prepare to submit the NFT
        item.set('name', createItemNameField.value);
        item.set('description', createItemDecriptionField.value);
        item.set('nftFilePath', nftFilePath);
        item.set('nftFileHash', nftFileHash);
        item.set('metadataFilePath', nftFileMetadataFilePath);
        item.set('metadataFileHash', nftFileMetadataFileHash);
        item.set('nftId', nftId);
        item.set('nftContractAddress', TOKEN_CONTRACT_ADDRESS);

this is where the “uid” comes from:

/****************  When Item Sold Event  ******************/
    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);
              
            }
       
        }
    }

    /****************  When Item Added For Sale  ******************/
    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);
        }
    
    }

but in both cases those are not defined:

const params = {uid: `${item.attributes.uid}`};

as I can see in the dev tools:

<div id="itemsForSale">
  <div id="item-[object Object]">

and because of the smart contract that requires a uint256:

function buyItem(uint256 id) payable external ItemExists(id) IsForSale(id) HasTransferApproval(itemsForSale[id].tokenAddress, itemsForSale[id].tokenId) {
        require(msg.value >= itemsForSale[id].askingPrice, "Not enough funds sent");
        require(msg.sender != itemsForSale[id].seller);

        itemsForSale[id].isSold = true;
        activeItems[itemsForSale[id].tokenAddress][itemsForSale[id].tokenId] = false;

        IERC721(itemsForSale[id].tokenAddress).safeTransferFrom(itemsForSale[id].seller, msg.sender, itemsForSale[id].tokenId);

        itemsForSale[id].seller.transfer(msg.value);

        emit itemSold(id, msg.sender, itemsForSale[id].askingPrice);
    }
}

I’m getting this error:

index.js:223 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
    at h.formatParam (index.js:223)
    at index.js:99
    at Array.map (<anonymous>)
    at h.encodeParameters (index.js:93)
    at index.js:438
    at Array.map (<anonymous>)
    at Object.b._encodeMethodABI (index.js:437)
    at Object.b._processExecuteArguments (index.js:700)
    at Object.b._executeMethod (index.js:719)
    at buyItem (main.js:390)

it is defined in Moralis cloud functions:

Moralis.Cloud.define("getItems", async (request) => {  
  const query = new Moralis.Query("itemsForSale");  
  query.notEqualTo("isSold", true); 

  query.select("uid", "tokenAddress", "tokenId", "askingPrice", "token.token_uri", "token.symbol", "token.owner_of", "user.username", "user.avatar");
  
  const queryResults = await query.find({useMasterKey:true}); 
  const results = [];

  for (let i = 0; i < queryResults.length; ++i) {    

    if(!queryResults[i].attributes.token || !queryResults[i].attributes.user) continue;

    results.push({
        "uid": queryResults[i].attributes.objectId,
        "tokenId": queryResults[i].attributes.token_id,
        "tokenAddress": queryResults[i].attributes.token_address,
        "askingPrice": queryResults[i].attributes.askingPrice,


        "symbol": queryResults[i].attributes.token.attributes.symbol,
        "tokenUri": queryResults[i].attributes.token.attributes.token_uri,
        "ownerOf": queryResults[i].attributes.token.attributes.owner_of,

        "sellerUsername": queryResults[i].attributes.user.attributes.username,
        "sellerAvatar": queryResults[i].attributes.user.attributes.avatar,
    });
  }  
  return results;
});

Moralis.Cloud.define("getItem", async (request) => {  
  const query = new Moralis.Query("itemsForSale");  
  query.notEqualTo("uid", request.params.uid); 
  query.select("uid", "tokenAddress", "tokenId", "askingPrice", "token.token_uri", "token.symbol", "token.owner_of", "user.username", "user.avatar");
  
  const queryResult = await query.first({useMasterKey:true}); 
  if(!queryResult) return;
  return {
        "uid": queryResult.attributes.objectId,
        "tokenId": queryResult.attributes.token_id,
        "tokenAddress": queryResult.attributes.token_address,
        "askingPrice": queryResult.attributes.askingPrice,


        "symbol": queryResult.attributes.token.attributes.symbol,
        "tokenUri": queryResult.attributes.token.attributes.token_uri,
        "ownerOf": queryResult.attributes.token.attributes.owner_of,

        "sellerUsername": queryResult.attributes.user.attributes.username,
        "sellerAvatar": queryResult.attributes.user.attributes.avatar,
    };
});

does anyone know why I’m not getting the right id here?

const params = {uid: `${item.attributes.uid}`};

thanks

do you have this part?


it looks like the database table should have that uid row for ItemsForSale table
1 Like

It was :

results.push({
        "uid": queryResults[i].attributes.objectId,

instead of :

results.push({
        "uid": queryResults[i].attributes.uid,

like you send…

THANK YOU VERY MUCHHHHHH! =))
:grin: :love_you_gesture:

1 Like