(EDIT: Added some code so that people can see more explicitly what's going on)
I'm a newcomer to Ethereum who's building a project that allows users to communicate with a Smart Contract through a HTML/Javascript frontend. Users sign in with their MetaMask accounts, which inject the relevant web3 provider into the page, allowing for communication between them and the contract. They carry out various operations and finally submit a piece of data to the blockchain, the transaction being signed by their MetaMask accounts. The only problem is this: within my frontend, I need to query the contract for certain information (hasVotedBefore, for instance) before the frontend can decide how to proceed (a validation request, essentially). I used async-await to force execution to wait until these values return before loading the rest of the page (this is necessary given my specification). I was using async-await to accomplish this, and it was working fine...until I discovered that MetaMask is blind to async-await Promises, and it threw a massive fit, thinking that I was using synchronous methods with no callbacks. Attempts to add or revert to ordinary (function(result, error) style callbacks did, technically, solve this problem, but at the expense of bringing back an old one, namely the inability to properly wait for the hasVotedBefore to return before proceeding. So, I need a way to wait for this method to return, but I also need it to happen in a way that Metamask is capable of recognising.
So far, I've been pointed towards EthJS, but this is for a college project, and I don't have a lot of time left. My impression is that using EthJS would require the frontend to be refactored significantly, as well as requiring the contract itself to be changed. While I'd be willing to do this if there's no other choice, I've contemplated using a handful of nested callbacks to run this instead. I am well aware of "callback hell" and the loathed and feared status of nested callbacks among the web development community, but I just need it to work once. This code will never be used for any commercial project, and I'm running low on time, so please take those factors into account. All I need is a way of getting the frontend to wait for an asynchronous response, in a manner that MetaMask will recognise.
For instance, let's take the code for finding how many Proposals there are (this is part of the functionality of the deployed Contract) and then populating an array based on that.
async function getNumProps(){
console.log("getNumProps");
try{
numProps = await RegionalContract.howManyProposals();
}catch (err) {
console.log(err);
}
return numProps;
}
**irrelevant code**
async function populateProps(){
try{
console.log("populateProps");
numProps = await getNumProps();
**do a bunch of stuff that's not relevant here**
}catch(error){
console.log(error);
}
}
populateProps();
When I try to run this code, I get the following in the console:
Error: The MetaMask Web3 object does not support synchronous methods like eth_call without a callback parameter. See
https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-cli
Given what's been said already, what would you recommend that I do in order to get things working? Any advice is appreciated.
Thanks