I completely understand your frustration, I have been in your situation so many times.
Donât give up, just take a step back and go trough logically what is happening.
and if you reach some code that you donât really know what it is doing, then take your time and do some research on it.
But well done doing everything you can to read up on the error first before posting!
Now to your problem.
Letâs go through the process of understanding what is wrong.
If we look at the error message:
Cannot read property 'once' of undefined
and as we can see further down this happens at line 34.
So first of all, when you get the error: cannot read property âpropertyNameâ of undefined it basically means that it canât find the thing specified just before property name.
This can happen for at least two reasons:
- spelling mistake
Example:
var myString = "test";
console.log(nyString.length); // Notice the spelling mistake. I am using an 'n' instead of an 'm'
This will result in the error cannot read property 'length' of undefined
.
Why? Because nyString
is in fact not defined, we made a spelling mistake.
- Using a variable that has not your been initialized
Example:
var person;
$(document).ready(async function(){
person = await loadPersonFromRemoteServer();
});
console.log(person.name);
Here we will reach the console.log(person.name);
long before the person
has been set.
Why? Because $(document).ready()
is first of all not called until the document is in fact completely ready (ie. fully loaded), while the code outside that function runs immediately.
In your case we have this scenario.
You did the right thing moving the events inside the $(document).ready()
, however we have another âdelayed callâ or promise as it is called on this line:
window.ethereum.enable().then(function(accounts){ contractInstance = new web3.eth.Contract...
.
The function in which the contractInstance is set is in the âthenâ call.
This means that the code where your instance is defined is called first after ethereum has been enabled, which in reality can be done in an unknown future.
Meanwhile the code below that code block is executed.
In that code you have your event setup which tries to access the contractInstance that is still not initialized (since the then() function has not yet been called).
So when this code is reached: contractInstance.once('LogNewProvableQuery'...
, the contractInstance is not defined and you get the error message: cannot read property 'once' of undefined
.
So what do you have to do?
Well, without giving you the whole answer you should find a way to run the event initialization when you can guarantee that the contractInstance is set.
When you get this working you will probably get more errors.
for example in the connectMetamask function.
A tip here is that you already know the accounts of the user because they are stored in accounts
when window.ethereum.enable().then(function(accounts){
is called.
Best of luck, and let us know if you get stuck again!