Hi,
For the Videos âI cloned rarible in 24hoursâ⌠I guess I have a timing problem retrieving linked table data.
My server (0.0.232): https://1bxtbthptjkt.moralis.io:2053/server
=> testserevr to Ropsten (Toronto).
The call to the Cloud Function getItem returns âCannot read property âattributesâ of undefinedâ when called as a subscribe() - create action. Not when normally called.
What helps me is the Log at the server: Dashboard -> Logs -> Info (not auto updating, so click the âInfoâ link in the left menu panel )
To add logging, see: https://docs.moralis.io/moralis-server/cloud-functions#console-log
This is the getItem function inside the Cloud Functions of the server:
Moralis.Cloud.define("getItem", async (request) => {
const logger = Moralis.Cloud.getLogger();
const query = new Moralis.Query("ItemsForSale");
const uid = request.params.uid;
logger.info("getItem uid=" + uid);
query.equalTo("uid", 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 {};
logger.info("getItem queryResult=" + JSON.stringify(queryResult.attributes));
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,
};
});
In the main.js the getItem is called (1 of 2 times):
onItemAdded = async (item) => {
console.log("onItemAdded... item=", item);
const params = {uid: `${item.attributes.uid}`};
console.log("onItemAdded... params=", JSON.stringify(params));
const addedItem = await Moralis.Cloud.run("getItem", params);
console.log("onItemAdded... addedItem=", addedItem);
if (addedItem){
user = await Moralis.User.current();
console.log("onItemAdded... user=", user);
if (user){
if (user.get('accounts').includes(addedItem.ownerOf)){
const userItemListing = document.getElementById(`user-item-${item.tokenObjectId}`);
console.log("onItemAdded... userItemListing=", userItemListing);
if (userItemListing) userItemListing.parentNode.removeChild(userItemListing);
getAndRenderItemData(addedItem, renderUserItem);
return;
}
}
getAndRenderItemData(addedItem, renderItem);
}
}
And this onItemAdded is called from init as a subscribed action, when an item is created:
init = async () => {
console.log("init...");
hideElement(userItemsSection);
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();
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);
}
After creating an Item, after the 3 Metamask actions, when the item is added to the Moralis ItemsForSale table the subscribed action becomes activated and so the onItemAdded function, which run the getItem of the Cloud Functions.
The browsers console shows:
The server Info Log shows:
2021-06-13T15:19:04.050Z - TypeError: Cannot read property 'attributes' of undefined
at eval (eval at customUserPlugin (/moralis-server/cloud/main.js:8:21), <anonymous>:1:3315)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
2021-06-13T15:19:04.048Z - Failed running cloud function getItem for user M7FC1EmtVPGBjCf8KUivaIbb with:
Input: {"uid":"25"}
Error: {"message":"Cannot read property 'attributes' of undefined","code":141}
2021-06-13T15:19:04.047Z - getItem queryResult={"uid":"25","tokenId":"29","tokenAddress":"0x21a56aec91d44e84244b9e50a061c70b38ce322b","askingPrice":"11117777","createdAt":"2021-06-13T15:19:03.772Z","updatedAt":"2021-06-13T15:19:03.772Z"}
2021-06-13T15:19:04.038Z - getItem uid=25
Viewing the queryResult formatted:
I MISS the related Token and User fields!!
Is this a timing problem, since the subscribe action is directly after the creation of the record??
If i add the getItem call to the loadUserItems (to call it when opening âMy Itemsâ and see it only in Console of browser):
loadUserItems = async () => {
const params = {uid: "19"};
console.log("loadUserItems ##... params=", JSON.stringify(params));
const addedItem = await Moralis.Cloud.run("getItem", params);
console.log("loadUserItems ** addedItem=", addedItem);
console.log("loadUserItems...");
const ownedItems = await Moralis.Cloud.run("getUserItems");
console.log("loadUserItems... ownedItems=", ownedItems);
ownedItems.forEach(item => {
console.log("loadUserItems... item=", item);
const userItemListing = document.getElementById(`user-item-${item.tokenObjectId}`);
console.log("loadUserItems... userItemListing=", userItemListing);
if (userItemListing) return;
getAndRenderItemData(item, renderUserItem);
});
}
I get the right response with token and user fields:
The error i get âCannot read property âattributesâ of undefinedâ is pointing to the line:
âsymbolâ: queryResult.attributes.token.attributes.symbol,
of the getItem Clouf Function (!!).