Rarible clone. Data not populating issue

Hey guys
I’ve just finished part 12 of the Morarible NFT marketplace video.
I do not get the User column or the Token column in the ItemsForSale part of the database.
another issue that has come out of no where. My database stopped adding the ItemsForSale after I mint and put them up for sale. I have no errors in the terminal or console but this was working before.
Can someone help me.
Thank you in advance.

Javascript

const serverUrl = "https://vxnx9mu8hh9u.usemoralis.com:2053/server";

const appId = "z75nQcm3wcoe9xd9MK8c6Lye9akXiMw1QldhfvE6";

const TOKEN_CONTRACT_ADDRESS = "0x99495223da7dFE1A14d5224Bc90bad4a01F0e58A";

const MARKETPLACE_CONTRACT_ADDRESS = "0x5b71C0259d1cFa36DD71A2C308E5A6378db5977f";

Moralis.start({ serverUrl, appId });

init = async () => {

    hideElement(userItemsSection);

    hideElement(userInfo);

    hideElement(createItemForm);

    await Moralis.enableWeb3();

    web3 = new Web3(Moralis.provider);

    window.tokenContract = new web3.eth.Contract(tokenContractAbi, TOKEN_CONTRACT_ADDRESS);

    window.marketplaceContract = new web3.eth.Contract(marketplaceContractAbi, MARKETPLACE_CONTRACT_ADDRESS);

        initUser();

        loadUserItems();

           

}

initUser = async () => {

    if (await Moralis.User.current()){

        hideElement(userConnectButton);

        showElement(userProfileButton);

        showElement(openCreateItemButton);

        showElement(openUserItemsButton);

        loadItems();

    }else{

        showElement(userConnectButton);

        hideElement(userProfileButton);

        hideElement(openCreateItemButton);

        hideElement(createItemForm);

        hideElement(openUserItemsButton);

    }

}

login = async () => {

    try {

        await Moralis.authenticate();

        initUser();

    } catch (error) {

        alert(error)

    }

}

logout = async () => {

    await Moralis.User.logOut();

    hideElement(userInfo);

    initUser();

}

openUserInfo = async () => {

    user = await Moralis.User.current();

    if (user){    

        const email = user.get('email');

        if(email){

            userEmailField.value = email;

        }else{

            userEmailField.value = "";

        }

        userNameField.value = user.get('username');

        const userAvatar = user.get('avatar');

        if(userAvatar){

            userAvatarImg.src = userAvatar.url();

            showElement(userAvatarImg);

        }else{

            hideElement(userAvatarImg);

        }

        showElement(userInfo);

    }else{

        login();

    }

}

saveUserInfo = async () => {

    user.set('email', userEmailField.value);

    user.set('username', userNameField.value);

    if (userAvatarFile.files.length > 0) {

        const avatar = new Moralis.File("avatar1.jpg", userAvatarFile.files[0]);

        user.set('avatar', avatar);

    }

    await user.save();

    alert("User info saved successfully!");

    openUserInfo();

}

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

    }

}

loadUserItems = async () => {

    const params =  { token_address: TOKEN_CONTRACT_ADDRESS };

    const ownedItems = await Moralis.Cloud.run("getUserItems", params);

    ownedItems.forEach(item => {

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

        if (userItemListing) return;

        getAndRenderItemData(item, renderUserItem);

    });

    console.log(ownedItems)

}

loadItems = async () => {

    const params =  { token_address: TOKEN_CONTRACT_ADDRESS };

    const items = await Moralis.Cloud.run("getItems", params);

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

    });

}

createItem = async () => {

    if (createItemFile.files.length == 0){

        alert("Please select a file!");

        return;

    } else if (createItemNameField.value.length == 0){

        alert("Please give the item a name!");

        return;

    }

    mintNFT = async (metadataUri) => {

        console.log("mintNFT :", ethereum.selectedAddress)

        const receipt = await tokenContract.methods.createItem(metadataUri).send({from: ethereum.selectedAddress});;

   

        console.log(receipt);

   

        return receipt.events.Transfer.returnValues.tokenId;

    }

const nftFile = new Moralis.File("nftFile.jpg",createItemFile.files[0]);

await nftFile.saveIPFS();

const nftFilePath = nftFile.ipfs();

const nftFileHash = nftFile.hash();

const metadata = {

    name: createItemNameField.value,

    description: createItemDescriptionField.value,

    image: nftFilePath,

};

const nftFileMetadataFile = new Moralis.File("metadata.json", {base64 : btoa(JSON.stringify(metadata))});

await nftFileMetadataFile.saveIPFS();

const nftFileMetadataFilePath = nftFileMetadataFile.ipfs();

const nftFileMetadataFileHash = nftFileMetadataFile.hash();

const nftId = await mintNFT(nftFileMetadataFilePath);

const Item = Moralis.Object.extend("Item");

const item = new Item();

item.set('name', createItemNameField.value);

item.set('description', createItemDescriptionField.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);

await item.save();

console.log(item);

user = await Moralis.User.current();

const userAddress = user.get('ethAddress');

switch(createItemStatusField.value){

    case "0":

        return;

        case "1":

            await ensureMarketplaceIsApproved(nftId, TOKEN_CONTRACT_ADDRESS);

           

            await marketplaceContract.methods.addItemToMarket(nftId, TOKEN_CONTRACT_ADDRESS, createItemPriceField.value).send({from: userAddress });

            break;

            case "2":

                alert("Not yet supported!");

                return;

           

}

buyItem = async (item) => {

    user = await Moralis.User.current();

    const userAddress = user.get('ethAddress');

    if(!user)

    {

        login();

        return;

    }

    await marketplaceContract.methods.buyItem(item.uid).send({from: user.get('ethAddress'), value: item.askingPrice});

}

}

initTemplate = (id) => {

    const template = document.getElementById(id);

    template.id = "";

    template.parentNode.removeChild(template);

    return template;

}

renderUserItem = (item) => {

    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("p")[0].innerText = item.description;

    userItems.appendChild(userItem);

    userItems.id = `user-item-${item.tokenObjectId}`

    userItems.appendChild(userItem);

   

    console.log(userItem);

}

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("span")[0].innerText = item.sellerUsername;

    }

    itemForSale.getElementsByTagName("img")[0].src = item.image;

    itemForSale.getElementsByTagName("img")[0].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.uid}`;

    itemForSale.appendChild(itemForSale);

}

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

    })

}

loadItems2 = async () => {

    const params =  { token_address: TOKEN_CONTRACT_ADDRESS };

    const items = await Moralis.Cloud.run("getItems", params);

    console.log(items);

}

ensureMarketplaceIsApproved = async (tokenId, tokenAddress) => {

    user = await Moralis.User.current();

    const userAddress = user.get('ethAddress');

   

    console.log("ensureMarketplaceIsApproved",  userAddress);

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

    }

}

ensureMarketplaceIsApproved = async (tokenId, tokenAddress) => {

    console.log(tokenId);

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

    }

}

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

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

openUserItems = async () => {

    user = await Moralis.User.current();

    if (user){    

        showElement(userItemsSection);

    }else{

        login();

    }

}

//Navbar

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

userConnectButton.onclick = login;

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

userProfileButton.onclick = openUserInfo;

//Userinfo

const userInfo = document.getElementById("userInfo");

const userNameField = document.getElementById("txtUsername");

const userEmailField = document.getElementById("txtEmail");

const userAvatarImg = document.getElementById("imgAvatar");

const userAvatarFile = document.getElementById("fileAvatar");

document.getElementById("btnCloseUserInfo").onclick = () => hideElement(userInfo);

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

document.getElementById("btnSaveUserInfo").onclick = saveUserInfo;

//Item Creation

const createItemForm = document.getElementById("createItem");

const createItemNameField = document.getElementById("txtCreateItemName");

const createItemDescriptionField = document.getElementById("txtCreateItemDescription");

const createItemPriceField = document.getElementById("numCreateItemPrice");

const createItemStatusField = document.getElementById("selectCreateItemStatus");

const createItemFile = document.getElementById("fileCreateItemFile");

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

openCreateItemButton.onclick = () => showElement(createItemForm);

document.getElementById("btnCloseCreateItem").onclick = () => hideElement(createItemForm);

document.getElementById("btnCreateItem").onclick = createItem;

//User Items

const userItemsSection = document.getElementById("userItems");

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

document.getElementById("btnCloseUserItems").onclick = () => hideElement(userItemsSection);

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

openUserItemsButton.onclick = openUserItems;

const userItemTemplate = initTemplate("itemTemplate");

const marketplaceItemTemplate = initTemplate("marketplaceItemTemplate");

init();

Cloud function

Moralis.Cloud.define("getUserItems", async (request) => {

  const options = { address: request.params.token_address, chain: "ropsten" };

  const NFTowners = await Moralis.Web3API.token.getNFTOwners(options);

  const queryResults = NFTowners.result.filter(x => x.owner_of == request.user.attributes.accounts);

const results = [];

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

  results.push({

    "tokenObjectId": queryResults[i].id,

    "tokenid": queryResults[i].token_id,

    "tokenAddress": queryResults[i].token_address,

    "symbol": queryResults[i].symbol,

    "tokenUri": queryResults[i].token_uri,

  });

}

return results;

});

  Moralis.Cloud.define("getItems", async (request) => {

     

    const query = new Moralis.Query("ItemsForSale");

    query.notEqualTo("isSold", true);

    query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id", "user.avatar","user.username");

 

    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.uid,

        "tokenId": queryResults[i].attributes.tokenId,

        "tokenAddress": queryResults[i].attributes.tokenAddress,

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

        "tokenObjectId": queryResults[i].attributes.token.id,

       

        "sellerUsername": queryResults[i].attributes.user.attributes.username,

        "sellerAvatar": queryResults[i].attributes.user.attributes.avatar,

      });

    }

 

    return results;

  });

 

  Moralis.Cloud.beforeSave("ItemsForSale", async (request) => {

 

    const options = { address: "0xF276579917F17F5a157251C02d46993c1c7E2e42", chain: "ropsten" };

    const NFTowners = await Moralis.Web3API.token.getNFTOwners(options);

    const queryResults = NFTowners.result.filter(x => x.token_address == request.object.get('tokenAddress') && x.token_id == request.object.get('tokenId'));

    query.equalTo("token_address", request.object.get('tokenAddress'));

    query.equalTo("token_id", request.object.get('tokenId'));

    const object = queryResults[0];

    if (object){

      const owner = object.owner_of;

        const userQuery = new Moralis.Query(Moralis.User);

        userQuery.equalTo("accounts", owner);

        const userObject = await userQuery.first({useMasterKey:true});

        if (userObject){

            request.object.set('user', userObject);

        }

        request.object.set('token', object);

    }

  });

  Moralis.Cloud.define("getItem", async (request) => {

    const query = new Moralis.Query("ItemsForSale");

query.equalTo("uid", request.params.uid);

query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id","user.avatar","user.username");

const queryResult = await query.first({useMasterKey:true});

if (!queryResult) return;

return {

    "uid": queryResult.attributes.uid,

    "tokenId": queryResult.attributes.tokenId,

    "tokenAddress": queryResult.attributes.tokenAddress,

    "askingPrice": queryResult.attributes.askingPrice,

    "symbol": queryResult.attributes.token.attributes.symbol,

    "tokenUri": queryResult.attributes.token.attributes.token_uri,

    "ownerOf": queryResult.attributes.token.attributes.owner_of,

    "tokenObjectId": queryResult.attributes.token.id,

    "sellerUsername": queryResult.attributes.user.attributes.username,

    "sellerAvatar": queryResult.attributes.user.attributes.avatar,

  };

  });

Moralis.Cloud.beforeSave("SoldItems", async (request) => {

 

    const query = new Moralis.Query("ItemsForSale");

    query.equalTo("uid", request.object.get('uid'));

    const item = await query.first();

    if (item){

      request.object.set('item', item);

      item.set('isSold', true);

      await item.save();

         

      const userQuery = new Moralis.Query(Moralis.User);

        userQuery.equalTo("accounts", request.object.get('buyer'));

      const userObject = await userQuery.first({useMasterKey:true});

      if (userObject){

          request.object.set('user', userObject);

      }

    }

  });

Marketplace smart contract

pragma solidity ^0.8.0;

//SPDX-License-Identifier: UNLICENSED

import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";

contract MorarableMarketContract {

    struct AuctionItem {

        uint256 id;

        address tokenAddress;

        uint256 tokenId;

        address payable seller;

        uint256 askingPrice;

        bool isSold;

    }

    AuctionItem[] public itemsForSale;

    mapping (address => mapping (uint256 => bool)) activeItems;

event itemAdded(uint256 id, uint256 tokenId, address tokenAddress, uint256 askingPrice);

event itemSold(uint256 id, address buyer, uint256 askingPrice);

modifier OnlyItemOwner(address tokenAddress, uint256 tokenId){

    IERC721 tokenContract = IERC721(tokenAddress);

    require(tokenContract.ownerOf(tokenId) == msg.sender);

    _;

}

modifier HasTransferApproval(address tokenAddress, uint256 tokenId){

    IERC721 tokenContract = IERC721(tokenAddress);

    require(tokenContract.getApproved(tokenId) == address(this));

    _;

}

modifier ItemExists(uint256 id){

    require(id < itemsForSale.length && itemsForSale[id].id == id, "could not find them");

    _;

}

modifier IsForSale(uint256 id){

    require(itemsForSale[id].isSold == false, "Item is already sold!");

    _;

}

    function addItemToMarket(uint256 tokenId, address tokenAddress, uint256 askingPrice) OnlyItemOwner(tokenAddress,tokenId) HasTransferApproval(tokenAddress,tokenId) external returns (uint256){

        require(activeItems[tokenAddress][tokenId] == false, "Item is already up for sale!");

        uint256 newItemId = itemsForSale.length;

        itemsForSale.push(AuctionItem(newItemId, tokenAddress, tokenId, payable(msg.sender), askingPrice, false));

        activeItems[tokenAddress][tokenId] = true;

        assert(itemsForSale[newItemId].id == newItemId);

        emit itemAdded(newItemId, tokenId, tokenAddress, askingPrice);

        return newItemId;

    }

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

}

}

Hey
I’ve been able to fix the issue with my ItemsForSale now turning up in the database.
I’m still continuing with trying to get the User column and Token column.
Cheers

Friendly update.
I’m still trying to get the User and Token columns in the Moralis database.
Cheers

Can you show the function using which you are trying to get the User and Token columns data?

Moralis.Cloud.define("getUserItems", async (request) => {

  const options = { address: request.params.token_address, chain: "ropsten" };

  const NFTowners = await Moralis.Web3API.token.getNFTOwners(options);

  const queryResults = NFTowners.result.filter(x => x.owner_of == request.user.attributes.accounts);

  const results = [];

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

    results.push({

      "tokenObjectId": queryResults[i].id,

      "tokenid": queryResults[i].token_id,

      "tokenAddress": queryResults[i].token_address,

      "symbol": queryResults[i].symbol,

      "tokenUri": queryResults[i].token_uri,

    });

  }

  return results;

});

Moralis.Cloud.beforeSave("ItemsForSale", async (request) => {

  const options = { address: "0xF276579917F17F5a157251C02d46993c1c7E2e42", chain: "ropsten" };

  const NFTowners = await Moralis.Web3API.token.getNFTOwners(options);

  const queryResults = NFTowners.result.filter(x => x.token_address == request.object.get('tokenAddress') && x.token_id == request.object.get('tokenId'));

  //query.equalTo("token_address", request.object.get('tokenAddress'));

  //query.equalTo("token_id", request.object.get('tokenId'));

  const object = queryResults[0];

  if (object){

    const owner = object.owner_of;

      const userQuery = new Moralis.Query(Moralis.User);

      userQuery.equalTo("accounts", owner);

      const userObject = await userQuery.first({useMasterKey:true});

      if (userObject){

          request.object.set('user', userObject);

      }

      //request.object.set('token', object);

  }

});

Moralis.Cloud.beforeSave("SoldItems", async (request) => {

  const query = new Moralis.Query("ItemsForSale");

  query.equalTo("uid", request.object.get('uid'));

  const item = await query.first();

  if (item){

    request.object.set('item', item);

    item.set('isSold', true);

    await item.save();

     

    const userQuery = new Moralis.Query(Moralis.User);

      userQuery.equalTo("accounts", request.object.get('buyer'));

    const userObject = await userQuery.first({useMasterKey:true});

    if (userObject){

        request.object.set('user', userObject);

    }

  }

});    

Moralis.Cloud.define("getItems", async (request) => {

 const query = new Moralis.Query("ItemsForSale");

query.notEqualTo("isSold", true);

query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id", "user.avatar","user.username");

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.uid,

  "tokenId": queryResults[i].attributes.tokenId,

  "tokenAddress": queryResults[i].attributes.tokenAddress,

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

  "tokenObjectId": queryResults[i].attributes.token.id,

 

  "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.equalTo("uid", request.params.uid);

query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id","user.avatar","user.username");

const queryResult = await query.first({useMasterKey:true});

if (!queryResult) return;

return {

  "uid": queryResult.attributes.uid,

  "tokenId": queryResult.attributes.tokenId,

  "tokenAddress": queryResult.attributes.tokenAddress,

  "askingPrice": queryResult.attributes.askingPrice,

  "symbol": queryResult.attributes.token.attributes.symbol,

  "tokenUri": queryResult.attributes.token.attributes.token_uri,

  "ownerOf": queryResult.attributes.token.attributes.owner_of,

  "tokenObjectId": queryResult.attributes.token.id,

  "sellerUsername": queryResult.attributes.user.attributes.username,

  "sellerAvatar": queryResult.attributes.user.attributes.avatar,

};

});

I’ve also been trying with this.

Moralis.Cloud.define("getUserItems", async (request) => {

  	const options = { address: request.params.token_address, chain: "ropsten" };
  	const NFTowners = await Moralis.Web3API.token.getNFTOwners(options);
  	const queryResults = NFTowners.result.filter(x => x.owner_of == request.user.attributes.accounts);
    const results = [];
 	for (let i = 0; i < queryResults.length; ++i) {
      results.push({
        "id": queryResults[i].attributes.ObjectId,
        "tokenid": queryResults[i].attributes.token_id,
        "tokenAddress": queryResults[i].attributes.token_address,
        "symbol": queryResults[i].attributes.symbol,
        "tokenUri": queryResults[i].attributes.token_uri,
      });
    }
    return results;
  });

Moralis.Cloud.beforeSave("ItemsForSale", async (request) => {
  
    const query = new Moralis.Query("EthNFTTransfers");
  	query.equalTo("token_address", request.object.get('tokenAddress'));
    query.equalTo("token_id", request.object.get('tokenId'));
    const object = await query.first();
    if (object){
    	const owner = object.attributes.owner_of;
        const userQuery = new Moralis.Query(Moralis.User);	
        userQuery.equalTo("accounts", owner);
        const userObject = await userQuery.first({useMasterKey:true});
        if (userObject){
            request.object.set('user', userObject);
        }
      	request.object.set('token', object);
    }
  });

Moralis.Cloud.beforeSave("SoldItems", async (request) => {
  
    const query = new Moralis.Query("ItemsForSale");
    query.equalTo("uid", request.object.get('uid'));
    const item = await query.first();
    if (item){
      request.object.set('item', item);
      item.set('isSold', true);
      await item.save();
      
    
      const userQuery = new Moralis.Query(Moralis.User);
        userQuery.equalTo("accounts", request.object.get('buyer'));
      const userObject = await userQuery.first({useMasterKey:true});
      if (userObject){
          request.object.set('user', userObject);
      }
    }
  });    

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

   if (request.user){
     query.notContainedIn("token.owner_of", request.user.attributes.accounts);
   }
   query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id", "user.avatar","user.username");

    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.uid,
        "tokenId": queryResults[i].attributes.tokenId,
        "tokenAddress": queryResults[i].attributes.tokenAddress,
        "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.equalTo("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.uid,
        "tokenId": queryResult.attributes.tokenId,
        "tokenAddress": queryResult.attributes.tokenAddress,
        "askingPrice": queryResult.attributes.askingPrice,
  
        "symbol": queryResult.attributes.token.attributes.symbol,
        "tokenUri": queryResult.attributes.token.attributes.token_uri,
        "ownerOf": queryResult.attributes.token.attributes.owner_of,
        "tokenObjectId": queryResult.attributes.token.id,
  
        "sellerUsername": queryResult.attributes.user.attributes.username,
        "sellerAvatar": queryResult.attributes.user.attributes.avatar,
      };
  });

Replace this with request.user.attributes.accounts[0] in getUserItems and getItems function and check it it fixes.

1 Like

Hey John
I’ve fixed this issue now thank you.
I have the User and Token columns in the database and everything works on my Dapp. I have 1 error that is unexpected token JSON in my console and I’m not sure why its there and it doesnt effect anything on my Dapp either.
Cheers

Screenshot json unexspected token

Can you show the code which is causing this?

Probably you are trying to read data which is not json.

Hey John
I’m not sure what code is causing this error but out of no where this happened. I haven’t changed any code and I just refreshed the page. I’m confused how and why thus came out of no where. Could it be the moralis server?
Cheers

Screenshot 2022-07-12 164939 final

Everything seems to be working still and its still populating the database with the NFT’s that are minted and put up for sale. Ill do some trial and error and see if i can get the errors to disappear

1 Like

Hi John
I got those errors to disappear now. I only have the unexpected token in Json at position 0.
Cheers

Screenshot 2022-07-13

The Unexpected token < in JSON error means the response is not in JSON format - for example this can happen if you’re fetching a link that doesn’t resolve (and the response returns some HTML). Check what you’re trying to fetch.

1 Like

Hi Glad
Ok thank you.
it would be in this part of my Main.js file I think. I haven’t changed anything but ill do some trial and error. :slight_smile:
Cheers

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

    })

}

Hi Glad
I’ve been doing some trial and error and nothing is fixing the issue. I’m abit lost at what it could be now.
Cheers.

HTML

<!DOCTYPE html>

<html lang="en">

<head>

    <link rel="shortcut icon" href="">

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Moraribles</title>

    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">

    <link rel="stylesheet" href="main.css">

 

</head>

<body class="bg-dark">

    <nav class="navbar navbar-expand-lg navbar-dark bg-transparent border-bottom border-light">

       

          <a class="navbar-brand btn btn-outline-moralis" href="#">Morarible</a>

          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">

            <span class="navbar-toggler-icon"></span>

          </button>

          <div class="collapse navbar-collapse" id="navbarNav">

            <form class="mx-2 d-inline flex-md-fill">

              <input type="search" class="bg-transparent border-light form-control text-light mr-sm-2 rounded-pill" placeholder="search by item or creator">

            </form>

            <ul class="navbar-nav mr-auto">

              <li class="nav-item">

                <a class="nav-link" id="btnMyItems" href="#">My Items</a>

              </li>

            </ul>

            <div class="d-flex">

              <button class="btn btn-primary rounded-pill my-2 my-sm-0 mr-md-2" id="btnOpenCreateItem">Create</button>

              <button class="btn btn-outline-moralis rounded-pill my-2 my-sm-0" id="btnConnect">Connect Wallet</button>

              <button class="btn btn-outline-moralis rounded-pill my-2 my-sm-0" id="btnUserInfo">Profile</button>

   

            </div>

           </div>

      </nav>

  <div class="container"></div>

      <div class="row row-cols-1 row-cols-md-4 mt-5" id="itemsForSale">

 </div>

<div class="col mb-4" id="marketplaceItemTemplate">

  <div class="card h-100 border-light  bg-transparent text-light">

    <nav class="card-header navbar navbar-dark text-light p-1">

        <img src="" alt="">

        <span></span>

     </nav>  

     <img src="..." class="card-img-top" alt="...">

     <div class="card-body d-flex align-items-end">

          <div class="w-100">

            <h5 class="card-title"></h5>

            <p class="card-text"></p>

            <button class="btn btn-primary">

          </div>

        <h5 class="card-title"></h5>

       <p class="card-text"></p>

       <button class="btn btn-primary"></button>

     </div>

  </div>

</div>

    <div id="userInfo">

        <h4>User Profile</h4>

        <input type="text" id="txtUsername" required placeholder="Enter username">

        <input type="text" id="txtEmail" placeholder="Enter email">

        <small>Optional</small>

        <img width="50" height="50" src="" id="imgAvatar" alt="">

        <label for="fileAvatar">Select Avatar</label>

        <input type="file" id="fileAvatar">

        <button id="btnLogOut">Log out</button>

        <button id="btnCloseUserInfo">Close</button>

        <button id="btnSaveUserInfo">Save</button>

    </div>

    <div id="createItem">

        <h4>Create Item</h4>

        <input type="text" id="txtCreateItemName" required placeholder="Enter name">

        <textarea id="txtCreateItemDescription" cols="30" rows="5" placeholder="Enter description"></textarea>

        <input type="number" min="1" step="1" id="numCreateItemPrice" placeholder="Enter price" required>

   

        <label for="selectCreateItemStatus">Status</label>

        <select id="selectCreateItemStatus">        

            <option value="0">Not for sale</option>

            <option value="1">Instant buy</option>

            <option value="2">Accept Offers</option>

        </select>

        <label for="fileCreateItemFile">Select File</label>

        <input type="file" id="fileCreateItemFile">

        <button id="btnCloseCreateItem">Close</button>

        <button id="btnCreateItem">Create!</button>

    </div>

    <div id="userItems">

      <h4>My Items</h4>

      <div id="userItemsList"></div>

      <button id="btnCloseUserItems">Close</button>

    </div>

    <div id="itemsForSale"></div>

    <div id="itemTemplate">

      <img src="" alt="">

      <h5></h5>

      <p></p>

      <input type="number" min="1" step="1">

      <button>Put For Sale</button>

    </div>

    <div id="marketplaceItemTemplate">

      <img src="" alt="">

      <h6></h6>

      <img src="" alt="">

      <h5></h5>

      <p></p>

      <button class="btn btn-primary btn-block"></button>

    </div>

           

    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>

    <script src="https://unpkg.com/moralis@latest/dist/moralis.js"></script>

    <script src="main.js"></script>

    <script src="abi.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>

</body>

</html>

Javascript

const serverUrl = "https://vxnx9mu8hh9u.usemoralis.com:2053/server";

const appId = "z75nQcm3wcoe9xd9MK8c6Lye9akXiMw1QldhfvE6";

const TOKEN_CONTRACT_ADDRESS = "0x99495223da7dFE1A14d5224Bc90bad4a01F0e58A";

const MARKETPLACE_CONTRACT_ADDRESS = "0x5b71C0259d1cFa36DD71A2C308E5A6378db5977f";

Moralis.start({ serverUrl, appId });

init = async () => {

    hideElement(userItemsSection);

    hideElement(userInfo);

    hideElement(createItemForm);

    await Moralis.enableWeb3();

    web3 = new Web3(Moralis.provider);

    window.tokenContract = new web3.eth.Contract(tokenContractAbi, TOKEN_CONTRACT_ADDRESS);

    window.marketplaceContract = new web3.eth.Contract(marketplaceContractAbi, MARKETPLACE_CONTRACT_ADDRESS);

        initUser();

        loadUserItems();

        loadItems();

        loadItems2();

        openCreateItemButton();

           

}

initUser = async () => {

    if (await Moralis.User.current()){

        hideElement(userConnectButton);

        showElement(userProfileButton);

        showElement(openCreateItemButton);

        showElement(openUserItemsButton);

    }else{

        showElement(userConnectButton);

        hideElement(userProfileButton);

        hideElement(openCreateItemButton);

        hideElement(createItemForm);

        hideElement(openUserItemsButton);

    }

}

login = async () => {

    try {

        await Moralis.authenticate();

        initUser();

    } catch (error) {

        alert(error)

    }

}

logout = async () => {

    await Moralis.User.logOut();

    hideElement(userInfo);

    initUser();

}

openUserInfo = async () => {

    user = await Moralis.User.current();

    if (user){    

        const email = user.get('email');

        if(email){

            userEmailField.value = email;

        }else{

            userEmailField.value = "";

        }

        userNameField.value = user.get('username');

        const userAvatar = user.get('avatar');

        if(userAvatar){

            userAvatarImg.src = userAvatar.url();

            showElement(userAvatarImg);

        }else{

            hideElement(userAvatarImg);

        }

        showElement(userInfo);

    }else{

        login();

    }

}

saveUserInfo = async () => {

    user.set('email', userEmailField.value);

    user.set('username', userNameField.value);

    if (userAvatarFile.files.length > 0) {

        const avatar = new Moralis.File("avatar1.jpg", userAvatarFile.files[0]);

        user.set('avatar', avatar);

    }

    await user.save();

    alert("User info saved successfully!");

    openUserInfo();

}

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

    }

}

loadUserItems = async () => {

    const params =  { token_address: TOKEN_CONTRACT_ADDRESS };

    const ownedItems = await Moralis.Cloud.run("getUserItems", params);

    ownedItems.forEach(item => {

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

        if (userItemListing) return;

        getAndRenderItemData(item, renderUserItem);

    });

    console.log(ownedItems)

}

loadItems = async () => {

    const items = await Moralis.Cloud.run("getItems");

    items.forEach(item =>{

        getAndRenderItemData(item, renderItem);

    });

}

createItem = async () => {

    if (createItemFile.files.length == 0){

        alert("Please select a file!");

        return;

    } else if (createItemNameField.value.length == 0){

        alert("Please give the item a name!");

        return;

    }

    mintNFT = async (metadataUri) => {

        console.log("mintNFT :", ethereum.selectedAddress)

        const receipt = await tokenContract.methods.createItem(metadataUri).send({from: ethereum.selectedAddress});;

   

        console.log(receipt);

   

        return receipt.events.Transfer.returnValues.tokenId;

    }

const nftFile = new Moralis.File("nftFile.jpg",createItemFile.files[0]);

await nftFile.saveIPFS();

const nftFilePath = nftFile.ipfs();

const nftFileHash = nftFile.hash();

const metadata = {

    name: createItemNameField.value,

    description: createItemDescriptionField.value,

    image: nftFilePath,

};

const nftFileMetadataFile = new Moralis.File("metadata.json", {base64 : btoa(JSON.stringify(metadata))});

await nftFileMetadataFile.saveIPFS();

const nftFileMetadataFilePath = nftFileMetadataFile.ipfs();

const nftFileMetadataFileHash = nftFileMetadataFile.hash();

const nftId = await mintNFT(nftFileMetadataFilePath);

const Item = Moralis.Object.extend("Item");

const item = new Item();

item.set('name', createItemNameField.value);

item.set('description', createItemDescriptionField.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);

await item.save();

console.log(item);

user = await Moralis.User.current();

const userAddress = user.get('ethAddress');

switch(createItemStatusField.value){

    case "0":

        return;

        case "1":

            await ensureMarketplaceIsApproved(nftId, TOKEN_CONTRACT_ADDRESS);

           

            await marketplaceContract.methods.addItemToMarket(nftId, TOKEN_CONTRACT_ADDRESS, createItemPriceField.value).send({from: userAddress });

            break;

            case "2":

                alert("Not yet supported!");

                return;

           

}

buyItem = async (item) => {

    user = await Moralis.User.current();

    const userAddress = user.get('ethAddress');

    if(!user)

    {

        login();

        return;

    }

    await marketplaceContract.methods.buyItem(item.uid).send({from: user.get('ethAddress'), value: item.askingPrice});

}

}

initTemplate = (id) => {

    const template = document.getElementById(id);

    template.id = "";

    template.parentNode.removeChild(template);

    return template;

}

    renderUserItem = async  (item) => {

        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("p")[0].innerText = item.description;

        userItems.appendChild(userItem);

        console.log(userItems);

   

    }

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("img")[0].src = item.image;

    itemForSale.getElementsByTagName("img")[0].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.uid}`;

    itemForSale.appendChild(itemForSale);

}

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

    })

}

loadItems2 = async () => {

    const params =  { token_address: TOKEN_CONTRACT_ADDRESS };

    const items = await Moralis.Cloud.run("getItems", params);

    console.log(items);

}

ensureMarketplaceIsApproved = async (tokenId, tokenAddress) => {

    user = await Moralis.User.current();

    const userAddress = user.get('ethAddress');

   

    console.log("ensureMarketplaceIsApproved",  userAddress);

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

    }

}

ensureMarketplaceIsApproved = async (tokenId, tokenAddress) => {

    console.log(tokenId);

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

    }

}

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

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

openUserItems = async () => {

    user = await Moralis.User.current();

    if (user){    

        showElement(userItemsSection);

    }else{

        login();

    }

}

//Navbar

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

userConnectButton.onclick = login;

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

userProfileButton.onclick = openUserInfo;

//Userinfo

const userInfo = document.getElementById("userInfo");

const userNameField = document.getElementById("txtUsername");

const userEmailField = document.getElementById("txtEmail");

const userAvatarImg = document.getElementById("imgAvatar");

const userAvatarFile = document.getElementById("fileAvatar");

document.getElementById("btnCloseUserInfo").onclick = () => hideElement(userInfo);

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

document.getElementById("btnSaveUserInfo").onclick = saveUserInfo;

//Item Creation

const createItemForm = document.getElementById("createItem");

const createItemNameField = document.getElementById("txtCreateItemName");

const createItemDescriptionField = document.getElementById("txtCreateItemDescription");

const createItemPriceField = document.getElementById("numCreateItemPrice");

const createItemStatusField = document.getElementById("selectCreateItemStatus");

const createItemFile = document.getElementById("fileCreateItemFile");

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

openCreateItemButton.onclick = () => showElement(createItemForm);

document.getElementById("btnCloseCreateItem").onclick = () => hideElement(createItemForm);

document.getElementById("btnCreateItem").onclick = createItem;

//User Items

const userItemsSection = document.getElementById("userItems");

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

document.getElementById("btnCloseUserItems").onclick = () => hideElement(userItemsSection);

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

openUserItemsButton.onclick = openUserItems;

const userItemTemplate = initTemplate("itemTemplate");

const marketplaceItemTemplate = initTemplate("marketplaceItemTemplate");

//Items for sale

const itemsForSale = document.getElementById("itemsForSale");

init();

Cloud function

Moralis.Cloud.define("getUserItems", async (request) => {

  const options = { address: request.params.token_address, chain: "ropsten" };

  const NFTowners = await Moralis.Web3API.token.getNFTOwners(options);

  const queryResults = NFTowners.result.filter(x => x.owner_of == request.user.attributes.accounts);

  const results = [];

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

    results.push({

      "id": queryResults[i].attributes.ObjectId,

      "tokenid": queryResults[i].attributes.token_id,

      "tokenAddress": queryResults[i].attributes.token_address,

      "symbol": queryResults[i].attributes.symbol,

      "tokenUri": queryResults[i].attributes.token_uri,

    });

  }

  return results;

});

Moralis.Cloud.beforeSave("ItemsForSale", async (request) => {

  const query = new Moralis.Query("EthNFTTransfers");

  query.equalTo("token_address", request.object.get('tokenAddress'));

  query.equalTo("token_id", request.object.get('tokenId'));

  const object = await query.first();

  if (object){

    const owner = object.attributes.owner_of;

      const userQuery = new Moralis.Query(Moralis.User);  

      userQuery.equalTo("accounts", owner);

      const userObject = await userQuery.first({useMasterKey:true});

      if (userObject){

          request.object.set('user', userObject);

      }

      request.object.set('token', object);

  }

});

Moralis.Cloud.beforeSave("SoldItems", async (request) => {

  const query = new Moralis.Query("ItemsForSale");

  query.equalTo("uid", request.object.get('uid'));

  const item = await query.first();

  if (item){

    request.object.set('item', item);

    item.set('isSold', true);

    await item.save();

     

    const userQuery = new Moralis.Query(Moralis.User);

      userQuery.equalTo("accounts", request.object.get('buyer'));

    const userObject = await userQuery.first({useMasterKey:true});

    if (userObject){

        request.object.set('user', userObject);

    }

  }

});    

Moralis.Cloud.define("getItems", async (request) => {

   

  const query = new Moralis.Query("ItemsForSale");

  query.notEqualTo("isSold", true);

 if (request.user){

   query.notContainedIn("token.owner_of", request.user.attributes.accounts);

 }

 query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id", "user.avatar","user.username");

  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.uid,

      "tokenId": queryResults[i].attributes.tokenId,

      "tokenAddress": queryResults[i].attributes.tokenAddress,

      "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.equalTo("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.uid,

      "tokenId": queryResult.attributes.tokenId,

      "tokenAddress": queryResult.attributes.tokenAddress,

      "askingPrice": queryResult.attributes.askingPrice,

      "symbol": queryResult.attributes.token.attributes.symbol,

      "tokenUri": queryResult.attributes.token.attributes.token_uri,

      "ownerOf": queryResult.attributes.token.attributes.owner_of,

      "tokenObjectId": queryResult.attributes.token.id,

      "sellerUsername": queryResult.attributes.user.attributes.username,

      "sellerAvatar": queryResult.attributes.user.attributes.avatar,

    };

});

marketplace smart contract

pragma solidity ^0.8.0;

//SPDX-License-Identifier: UNLICENSED

import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";

contract MorarableMarketContract {

    struct AuctionItem {

        uint256 id;

        address tokenAddress;

        uint256 tokenId;

        address payable seller;

        uint256 askingPrice;

        bool isSold;

    }

    AuctionItem[] public itemsForSale;

    mapping (address => mapping (uint256 => bool)) activeItems;

event itemAdded(uint256 id, uint256 tokenId, address tokenAddress, uint256 askingPrice);

event itemSold(uint256 id, address buyer, uint256 askingPrice);

modifier OnlyItemOwner(address tokenAddress, uint256 tokenId){

    IERC721 tokenContract = IERC721(tokenAddress);

    require(tokenContract.ownerOf(tokenId) == msg.sender);

    _;

}

modifier HasTransferApproval(address tokenAddress, uint256 tokenId){

    IERC721 tokenContract = IERC721(tokenAddress);

    require(tokenContract.getApproved(tokenId) == address(this));

    _;

}

modifier ItemExists(uint256 id){

    require(id < itemsForSale.length && itemsForSale[id].id == id, "could not find them");

    _;

}

modifier IsForSale(uint256 id){

    require(itemsForSale[id].isSold == false, "Item is already sold!");

    _;

}

    function addItemToMarket(uint256 tokenId, address tokenAddress, uint256 askingPrice) OnlyItemOwner(tokenAddress,tokenId) HasTransferApproval(tokenAddress,tokenId) external returns (uint256){

        require(activeItems[tokenAddress][tokenId] == false, "Item is already up for sale!");

        uint256 newItemId = itemsForSale.length;

        itemsForSale.push(AuctionItem(newItemId, tokenAddress, tokenId, payable(msg.sender), askingPrice, false));

        activeItems[tokenAddress][tokenId] = true;

        assert(itemsForSale[newItemId].id == newItemId);

        emit itemAdded(newItemId, tokenId, tokenAddress, askingPrice);

        return newItemId;

    }

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

}

}

morarible smart contract

pragma solidity ^0.8.0;

//SPDX-License-Identifier: UNLICENSED

import "../node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol";

import "../node_modules/@openzeppelin/contracts/utils/Counters.sol";

contract MorarableToken is ERC721 {

    using Counters for Counters.Counter;

    Counters.Counter private _tokenIds;

    constructor () ERC721("MorarableToken", "MORA"){}

    struct Item {

        uint256 id;

        address creator;

        string uri;

    }

    mapping (uint256 => Item) public Items;

    function createItem(string memory uri) public returns (uint256){

        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();

        _safeMint(msg.sender, newItemId);

        Items[newItemId] = Item(newItemId, msg.sender, uri);

        return newItemId;

    }

    function tokenURI(uint256 tokenId) public view override returns (string memory) {

        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

       return Items[tokenId].uri;

    }

}

Hi
I have the token Uri in my console and when I copy and paste it in a new window it has the correct token information. I’m starting to think its not the fetch token Uri part of my main.js.
This is one of my token Uri’s.
https://ipfs.moralis.io:2053/ipfs/QmXiMsbu7wMoEENfLz33Xo4DHwy1ymYnZq9usf7y18s783

On second thoughts I still think it actually is the fetch tokenUri part. I’m confused at where to go from here as its spelled correctly and was working yesterday. :slight_smile:

Try console.log of response and data to check if the returns in json format.

Hey John
This is what I got from both console.logs
Cheers

console.log of response