[SOLVED] Cant fetch EthNFTOwners

when I console log the data I get a return but when trying to fetch it I get a 404 error. Im pretty sure the issue is something simple

const serverUrl = "https://5afgk9nae19l.usemoralis.com:2053/server";
const appId = "lhSPMJb08k6pB25ESY87s7VxvnNZobzHLWHbs8yj";
Moralis.start({ serverUrl, appId });

const TOKEN_CONTRACT_ADDRESS = "0x11c168210646756b7B7db43977DFBE21cDCA350a";
// var Buffer = require('buffer/').Buffer  // note: the trailing slash is important!

init = async () => {
  hideElement(userItemsSection);
  hideElement(userInfo);
  hideElement(createItemForm);
  window.web3 = await Moralis.Web3.enable();
  window.tokenContract = new web3.eth.Contract(tokenContractAbi, TOKEN_CONTRACT_ADDRESS);
  window.marketplaceContract = new web3.eth.Contract(marketplaceContractAbi, MARKETPLACE_CONTRACT_ADDRESS);
  initUser();
  // loadUserItems();
  
  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);
}

initUser = async () => {
  if (await Moralis.User.current())
  {
    window.web3 = await Moralis.Web3.enable();
    window.tokenContract = new web3.eth.Contract(tokenContractAbi, TOKEN_CONTRACT_ADDRESS);
    hideElement(userConnectButton);
    showElement(userProfileButton);
    showElement(openCreateItemButton);
    showElement(openUserItemsButton);
    loadUserItems();
  }
  else
  {
    showElement(userConnectButton);
    hideElement(userProfileButton);
    hideElement(openCreateItemButton);
    hideElement(openUserItemsButton);
  } 
}

initUser();

login = async () => {
  try {
      await Moralis.Web3.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{
      userUsernameField.value = "";
    }
    userUsernameField.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', userUsernameField.value);
  
  if (userAvatarFile.files.length > 0){
    // Moralis can handle any kind of file but her we specify jpegS
    const avatar = new Moralis.File("avatar.jpg", userAvatarFile.files[0]);
    //dont worry about name colisions theyr given names and track by element Id
    user.set('avatar', avatar);
  }
  await user.save();
  alert("We got your info stored!");
  openUserInfo();
}


createItem = async () => {
  if (createItemFile.files.length == 0){
    alert("Are you gonna select a file?");
    return;
  } else if (createItemNameField.value.length == 0){
    alert("You need to give the file a name!");
    return;
  }
  
  const nftFile = new Moralis.File("nftFile",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();
//  console.log(JSON.stringify(nftFileMetadataFile))
var nftFileMetadataFilePath = nftFileMetadataFile.ipfs();
var nftFileMetadataFileHash = nftFileMetadataFile.hash();

 const nftId = await mintNft(nftFileMetadataFilePath);
 
 const Item = Moralis.Object.extend("Item");
 //create new instance of the class
 const item = new Item(); 
 item.set('name', createItemNameField.value);
 item.set('description', createItemDescriptionField.value);
 item.set('nftFilePath', nftFilePath);
 item.set('nftFileHash', nftFileHash);
 item.set('nftFileMetadataFilePath', nftFileMetadataFilePath);
 item.set('MetadataFileHash', nftFileMetadataFileHash);
 item.set('nftId', nftId);
 item.set('nftContractAddress', TOKEN_CONTRACT_ADDRESS);
 await item.save();
 console.log(item);
}

mintNft = async (metadataUrl) => {
  const receipt = await tokenContract.methods.createItem(metadataUrl).send({from: ethereum.selectedAddress});
  console.log(receipt);
  return receipt.events.Transfer.returnValues.tokenId;
}

openUserItems = async () => {
  user = await Moralis.User.current();
  if (user){    
    showElement(userItemsSection);
  }else{
    login();
  }
}

loadUserItems = async () => {
  const ownedItems = await Moralis.Cloud.run("getUserItems");
  console.log(ownedItems);
  ownedItems.forEach(item => {
    getAndRenderItemData(item, renderUserItem);
  })
}
 

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

getAndRenderItemData = (item, renderFunction) => {
  fetch(item.tokenUri)
    .then(response => response.json())
    .then(data => {
       data.symbol = item.symbol;
       data.tokenId = item.tokenId;
       data.tokenAddress = item.tokenAddress;
        renderFunction(item);
    })
}

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

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

const openCreateItemButton = document.getElementById("btnOpenCreateItem");
openCreateItemButton.onclick = () => showElement(createItemForm);

//User Profile
const userProfileButton = document.getElementById("btnUserInfo");
userProfileButton.onclick = openUserInfo;

const userInfo = document.getElementById("userInfo");
const userUsernameField = document.getElementById("txtUsername");
const userEmailField = document.getElementById("txtEmail");
const userAvatarImg = document.getElementById("imgAvater");
const userAvatarFile = document.getElementById("fileAvatar");

document.getElementById("btnCloseUserInfo").onclick = () => hideElement(userInfo);
document.getElementById("btnSaveUserInfo").onclick = saveUserInfo;
document.getElementById("btnLogout").onclick = logOut;

//Item Creation
const createItemForm = document.getElementById("createItem");

const createItemNameField = document.getElementById("txtCreateItemName");
const createItemDescriptionField = document.getElementById("txtCreateItemDescription");
const createItemPriceField = document.getElementById("numberCreateItemPrice");
const createItemStatusField = document.getElementById("selectCreateItemStatus");
const createItemFile = document.getElementById("fileCreateItemFile");

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

init();


heres the cloud function

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

    const query = new Moralis.Query("EthNFTOwners");
    query.equalTo("contract_type", "ERC721");
    query.containedIn("owner_of", request.user.attributes.accounts);
    const queryResults = await query.find();
    const results = [];
    for (let i = 0; i < queryResults.length; ++i) {
      results.push({
        "tokenObjectId": queryResults[i].id,
        "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;
  });

what is the line that prints that data to the console?

this looks like the cloud function returns the data, and it may be a problem on displaying the data in html. you could add more logging, for example in that renderUserItem function

I followed your suggestion


It logs ok but still no display

solved
I was returning the item instead of the data