Passing Array Parameters to executeFunction

Hello,

When using executeFunction to call a contract function, how do I pass parameter value if it is an array?

For example, I have the following contract function (ABI Below):

{
    "inputs": [
      {
        "internalType": "uint256[]",
        "name": "streamIdList",
        "type": "uint256[]"
      },
      {
        "internalType": "address",
        "name": "who",
        "type": "address"
      }
    ],
    "name": "balanceOfStreams",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "totalBalance",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  }

streamIdList
And I am using the code below to call the function:

const [userStreams, setUserStreams] = useState([]);
.
.
console.log("----> userStreams(length): " + userStreams.length);
console.log("----> userStreams: " + JSON.stringify(userStreams));
const currentUser = Moralis.User.current();
console.log("----> currentUser.get('ethAddress'): " + currentUser.get("ethAddress"));
if (userStreams.length > 0) {
   const userStreamsIdList = userStreams.map(Number);
   console.log("-----> userStreamsIdList: " + JSON.stringify(userStreamsIdList));
   const balaceOfStreams = Moralis.executeFunction({ functionName: 'balanceOfStreams', 
      params: {
         streamIdList: userStreams,
         who: currentUser.get("ethAddress")
      }, 
      ...streamContractOptions
   });
   console.log("----> balaceOfStreams: " + JSON.stringify(balaceOfStreams));
}

in the console log, I see the following:

----> userStreams(length): 3
----> userStreams: ["100000","100001","100002"]
----> balaceOfStreams: {}

I am expecting to get back a non-empty result. I verified the same call using a different front-end and I do get the proper balance. Am I passing the array in the correct format?

Thanks in advance!

as a work around you can change the abi so that it has 3 different parameters instead of an array, I don’t know now if it is a problem with arrays on Moralis.executeFunction, you can also use Moralis.runContractFunction, but you may get into same problem

Thank you @cryptokid

The issue with changing the ABI is that the stream id list can have different sizes.

I tried the runContractFunction. Still not getting any results back, However, I also see the exception below in the log:

{
    "code": 141,
    "error": "Returned values aren't valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced."
}
1 Like

An update to my earlier reply. I realized that I did not set the “chain” when using runContractFunction. So I added this to the options:

chain: "avalanche testnet"

Now, I am getting the same result as before which is an empty result:

---> balaceOfStreams: {}

This is the same behaviour as using executeFunction().

Below is the code using runContractFunction():

const balaceOfStreams = Moralis.Web3API.native.runContractFunction({ 
   function_name: 'balanceOfStreams', 
   params: {
      streamIdList: userStreams,
      who: currentUser.get("ethAddress")
   }, 
   ...streamContractOptions_2
});

ok, probably it doesn’t work then

Ok, I feel really stupid. The issue was that I did not have “await” before calling the contract function. Here is the updated code:

const balaceOfStreams = await Moralis.executeFunction({ functionName: 'balanceOfStreams', 
  params: {
    streamIdList: userStreams,
    who: currentUser.get("ethAddress")
  }, 
  ...streamContractOptions
});

It is working now! smacks_head