event.watch is not a function in web3.0 v1.0
Use the snippet below instead, but remember that:
myContract
should be a variable you assigned which is an instance of your contract
MyEvent
should be replaced with the actual name of your event.
myContract.events.MyEvent({
filter: {myIndexedParam: [20,23], myOtherIndexedParam: '0x123456789...'}, // Using an array means OR: e.g. 20 or 23
fromBlock: 0
}, function(error, event){ console.log(event); })
.on('data', function(event){
console.log(event); // same results as the optional callback above
})
.on('changed', function(event){
// remove event from local database
})
.on('error', console.error);
Also see the docs here.
The async/await patern works with JavaScript Promises.
In order to make web3.js functions asynchronous, you need to pass a callback parameter:
As this API is designed to work with a local RPC node, all its
functions use synchronous HTTP requests by default.
If you want to make an asynchronous request, you can pass an optional
callback as the last parameter to most functions. All callbacks are
using an error first callback style:
web3.eth.getBlock(48, function(error, result){
if(!error)
console.log(JSON.stringify(result));
else
console.error(error);
})
If you want to then make this work with the async/await pattern, you will need to then wrap this asynchronous function into a promise, which is of the format:
new Promise( /* executor */ function(resolve, reject) { ... } );
Rather than do this over an over for each web3.js function, you can automate this process by creating a wrapper for javascript functions which includes the callback parameter and wraps it in a promise as so:
const promisify = (inner) =>
new Promise((resolve, reject) =>
inner((err, res) => {
if (err) {
reject(err);
} else {
resolve(res);
}
})
);
This can then be used really simply with nearly all existing web3.js functions:
async function getBalance() {
var address, wei, balance
address = document.getElementById("address").value;
wei = promisify(cb => web3.eth.getBalance(address, cb)) // simply wrap web3.js functions with the promisify function, also passing in a callback parameter
try {
balance = web3.fromWei(await wei, 'ether')
document.getElementById("output").innerHTML = balance + " ETH";
} catch (error) {
document.getElementById("output").innerHTML = error;
}
}
All of this information can be found on my blog where you can also find other small projects I have done which use this pattern.
Best Answer
This looks to me like a race condition.
The
watch
callback is executed asynchronously when data matching your filter is polled from the node. CallingmyEvent.watch
is non-blocking and as suchmyEvent.stopWatching()
will be called immediately afterwards.The result you will get depends on whether the polling completes in the milliseconds before
stopWatching
is called.This is non-deterministic - you might get different results each time you run it.