Unexpected token < in JSON (undefined) [I CLONED RARABLE IN 24 HOURS]

I am getting these errors when doing the Morarable tutorial:

It is related to my getAndRenderItemData function when fetching the tokenUri:

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);
        console.log(item);
    })
}

the console.log shows the items and their URIs, such as:

My cloud function seems correct in getItems:

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", "tokenAddress", "tokenId", "askingPrice", "token.token_uri", "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.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.username,
        "sellerAvatar": queryResults[i].attributes.user.avatar,
      });
    }
  
    return results;
  });

I know that the error means that it cant recognize the JSON so it converts to HTML, but i cant see where to find where this error is exactly.

Check the item.tokenUri youโ€™re trying to fetch; if this property doesnโ€™t exist in each item that you pass into getAndRenderItemData, then it will be undefined when you try to fetch it.

so ive had a look and tokenUri does not appear in getItems preview:

However, it does show when i use console.log (item.tokenUri):

i now know what the problem is:

My getItems cloud function has a query select. This does not seem to be picking up anything using user. or token. as shown below:

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

So in my itemsForSale cloud function, i use request.object.set getting both token. and user. .

This is shown here:

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

What am i doing wrong here?

Is it because i am calling it from the EthNFTTransfers table?
This table was the only one that has token_address and token_id.
Maybe i should change these equalTo values or can i also add another table to contribute to find user and token objects?

but then again, it may be due to this path:
"tokenUri": queryResults[i].attributes.token.attributes.token_uri,
within the getItems cloud function.

How will i be able to properly fix this issue?

Can you click on these error references and check where the error is pointed at.
image

Im not getting that error on line 240 anymore, but just to be sure, this is the start of line 240:

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

Im getting the error on line 230 which is fetch(item.tokenUri):

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);
        console.log(item.tokenUri);
    })
}

I know the error has to do with the the table relationships in the database, but just dont know where to move on from here because in the code above i use console.log(item.tokenUri) which returns each tokenUri.

This is my cloud function:

Moralis.Cloud.define("getUserItems", async (request) => {
  //sets params.
      const options = { address: request.params.token_address, chain: "ropsten", };
  //calls from web3api.
      const nftOwners = await Moralis.Web3API.token.getNFTOwners(options);
  //query results from nftOwners.
      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 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);
  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.uid,
    "tokenId": queryResults[i].attributes.tokenId,
    "tokenAddress": queryResults[i].attributes.tokenAddress,
    "askingPrice": queryResults[i].attributes.askingPrice,

    "symbol": queryResults[i].attributes.symbol,
    "tokenUri": queryResults[i].attributes.token_uri,
    "ownerOf": queryResults[i].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,
      };
  });