React-moralis noob question - multiple cloud functions same component

Using react-moralis, how can we call more than one cloud function in the same component with one cloud function needing a parameter?

Do you want to do concurrent calls or one after the other?

Can you give a more elaborate explanation of this?

You can just call the hook multiple times and it will be ok. You have to rename the returned value though like:

const { data: scoreData, error: scoreError, isLoading: scoreIsLoading } = useMoralisCloudFunction("topScores");
const { data: playerData, error: playerError, isLoading: playerIsLoading } = useMoralisCloudFunction("players");

or

const topScoreCloudQuery = useMoralisCloudFunction("topScores");
const playerCloudQuery = useMoralisCloudFunction("players");

// Use topScoreCloudQuery.data / topScoreCloudQuery.error etc. or playerCloudQuery.data / playerCloudQuery.error etc. anywhere

I think you could use data from the first cloud function as parameter in the second cloud function, if that is what you are trying to do. For example

const topScoreCloudQuery = useMoralisCloudFunction("topScores");
const playerCloudQuery = useMoralisCloudFunction("players", {minScore: topScoreCloudQuery.data});

Or something along those lines.
I hope this helps :slight_smile:

3 Likes

That is exactly what I was looking for thank you!

1 Like

@Erno
Would this work the same way for useWeb3ExecuteFunction react hook?

const { data: traitData, error: traitError, fetch: traitFetch, isFetching: traitFetching, isLoading: traitLoading } = useWeb3ExecuteFunction({
    abi: spotNFTAbiFuji,
    contractAddress: spotNFTContractFuji,
    functionName: "checkDNA",
    params: {
    DNA: currentDNA,
    },

I have to verify multiple things before minting using multiple functions in the contract. So for each different function-call for the same contract I must make brand new ones like this?

That’s correct. For each function you would need a separate useWeb3ExecuteFunction hook.

Of course, if your code becomes messy, you could create custom hooks yourself to clean things up (that’s what I do when I have multiple function calls, or in bigger apps. For example something like:

const useTrait = ({ currentDNA }) => {
  const {data, error, fetch, isFetching, isLoading} = useWeb3ExecuteFunction({
    abi: spotNFTAbiFuji,
    contractAddress: spotNFTContractFuji,
    functionName: "checkDNA",
    params: {
      DNA: currentDNA,
    },,
  });

  return {
    traitData: data,
    traitError: error,
    fetchTrait: fetch,
    traitIsFetching: isFetching,
    traitIsLoading: isLoading 
  };
};
const {traitData, traitIsLoading} = useTrait({currentDNA})
2 Likes

Thanks @Erno this is very useful! The above function returns 0 if DNA combo available and 1 if DNA combo already minted.
I am then using the data received from the above function in the following manner:

const [traitsAvailability, setTraitsAvailability] = useState('1')
useEffect(function() {
    if(currentDNA.length >=16) {
        traitFetch()
        .then((data)=> setTraitsAvailability(JSON.stringify(data)))
    }
            },[chosenTrait])

(Basically if DNA is more than 16, which means user has selected all 6 traits, then I store the returned value (0 or 1) using useState. However I notice since useState is async sometimes a blank/null/undefined value is captured on first attempt/ first render.

Do you have an example repo where I can see how you handle data received back from the contract call, and how you line up multiple function contract calls in a sequence?

You could call the functions in a try/catch block and assuming you’re using ethers.js do something like:

  const dnaCheck = async () =>{
    try{
       //if writing use a signer
      const signer = web3.getSigner();
      //else you can use a JSONRPC or HTTP provider
      const instance = new ethers.Contract(ContractAddress, abi, signer);
      const trait = await instance.checkDNA(DNA);
      const result = await trait.wait();
      if(result.status === 1){
       // follow up with another function with returned data
        await doAnotherFunctionCall();
      }
    } catch (error) {
      console.log(error.message);
    }
  }

I know it’s not using the useWeb3ExecuteFunction hook, but you get the idea. And if I remember correctly web3.js also has a status === 1 if the call/send was successful

Here’s an example in a repo I used for a minting/marketplace dapp: GitHub Repo

Hope that helps :slightly_smiling_face:

2 Likes