Hello i have a moralis database question

can you share how your current code and results look like

this code is working it returns the previous data of the objects but it does not add the user it is empty

Moralis.Cloud.define('getNft', async function(){

  const query = new Parse.Query('TokensMintedERC721')
  const results = await query.find({ useMasterKey: true});
  var newArr = []

  async function getUser(element) {

    const userPointer = element.get("user");
    await userPointer.fetch({ useMasterKey: true});
    let username = userPointer.get('username')
    let userAvatar = userPointer.get('userAvatar')
    // You can then get any value from the userPointer with userPointer.get('THE_VALUE')

    return {  username ,  userAvatar }
  }

  results.forEach( element => {
    let { username, userAvatar } = getUser(element)
    newArr = [...newArr, {...element,  username: username, userAvatar: userAvatar }]
  });

  
  return newArr;
  
});


in the :


  results.forEach( element => {
    let { username, userAvatar } = getUser(element)
    newArr = [...newArr, {...element,  username: username, userAvatar: userAvatar }]
  });


I have tried the following ways:

with ...elements it works, it returns the data that exists, with the following it returns the empty objects without username and without userAvatar and with the last one, adding the name to the object and assigning the value also returns it empty

 newArr = [...newArr, { username: username, userAvatar: userAvatar }]
    newArr = [...newArr, {...element, }]
    newArr = [...newArr, {...element,  username, userAvatar}]

here example :arrow_up:

Try with this code. I updated for loop with an async function, added a const data in getUser function and used .push to update the array.

Moralis.Cloud.define('getNft', async function(){
const query = new Moralis.Query("TokensMintedERC721");
  const results = await query.find({ useMasterKey: true });
  var newArr = [];

  async function getUser(element) {
    const userPointer = element.get("user");
    const data = await userPointer.fetch({ useMasterKey: true });
    let username = data.get("username");
    let userAvatar = data.get("userAvatar");
    // You can then get any value from the userPointer with userPointer.get('THE_VALUE')
    return { username, userAvatar };
  }

  results.forEach(async (element) => {
    let { username, userAvatar } = await getUser(element);
    newArr.push({ element, username: username, userAvatar: userAvatar });
  });

  return newArr;
});

This is the result I got.
image

It doesn’t work for me, not even with the same code :frowning: I don’t understand why

this is return data:

2022-10-05_01h50_00

Looking into it. The logic is correct, but somehow it is not working in cloud code.

and how else can I solve the problem of causality how do you call the cloud data?

What is your Moralis serverUrl / dapp URL?

https://avgcactb6lbt.usemoralis.com:2053/server

https://avgcactb6lbt.usemoralis.com:2053/server

Your getNft cloud function is different from johnversus’s, have you tried it as is?

if at this moment it is different because I am testing, but I tried the same function and it looks like in the attached image array 0

what part from that function doesn’t work as expected?
assuming that you did some debugging and logging with logger.info(JSON.stringify(variable_name))

If the problem is reading the user (the pointer), the log in the db info gives me this:

If you get the object id for a user object then you can always make another query with that object id to get the user object.

Yes, I know that I can generate another query so I have another request to the server, but if for scalability and ease the pointer can be used, it is better to obtain this relationship since it will not be the only one that I will apply. I comment on the progress I have made, yes to the function result.forEach I remove the async and it no longer returns it empty, it returns it full but it does not add the user, what other way can I apply to obtain the pointer that refers to the user:


    async function getUser(element) {
      const userPointer = element.get('user');
      const data = await userPointer.fetch({ useMasterKey: true });
      let username = data.get("username");
      let userAvatar = data.get("userAvatar");

      return { username, userAvatar };
    }

This is how I extract the data:

let { username, userAvatar } = getUser(element);

if this function I leave it:

 results.map(async (element) => {
  let { username, userAvatar } = await getUser(element);
  // logger.info('forEach',JSON.stringify(username))

  newArr.push({ ...element, username: username, userAvatar: userAvatar });
});

As an asynchronous function does not return anything, if I remove the async it returns the array but does not add the user, what other way can I implement it?

you can use .include in the original query if you want it to also include the pointer data directly, sometimes it works

Could you give me an example please and thank you

a possible example

1 Like

In response to this error, the solution in the cloud was this:

Moralis.Cloud.define('getNftCarouselLive', async function(){

  const query = new Moralis.Query("ItemsMinted");
  const results = await query.find({ useMasterKey: true });  


  async function getUser(ownerAddress) {

    const queryUser = new Moralis.Query("User");
    queryUser.equalTo('ethAddress', ownerAddress)

    const resultUser = await queryUser.first({ useMasterKey: true });

    const username =  resultUser.attributes.username != null || undefined ? resultUser.attributes.username : '';
    const userAvatar =  resultUser.attributes.userAvatar != null || undefined ? resultUser.attributes.userAvatar : '';

    return {username, userAvatar }
  }

  const response = await Promise.all(
    results.map( async (value) => {
      
      const objStr =  JSON.stringify(value);
      const objJson = JSON.parse(objStr);
      const ownerAddress = objJson.ownerAddress;

      let newArr = [];

      const { username, userAvatar } = await getUser(ownerAddress); 


      newArr = {...objJson, username, userAvatar } 

      return newArr;
    }) 
  ) 

  return response;
});

The solution was to use a Promise.all to wait for all promises to resolve. This will cause all asynchronous code to be resolved in parallel. This means that if we have N number of asynchronous functions, the N functions will be executed in parallel and will be resolved without waiting for each other.

In other words, the time that Promise.all will take to resolve will be the slowest time of all N calls.

1 Like