[Ethereum] Web3.js/1.0: How to wait/loop until new event show up like watch()

eventsweb3js

On Web3.js/1.0 there is no watch() function for the contracts to retrieve events.

I have followed the following guide, web3.eth.Contract – Events – getPastEvents – example, and answer to retrieve emitted events.

  • event.watch(...) used to wait until a new event shows up and does not move on to the next instruction till watch is stopped.

In the following example if there is no event in between fromBlock and toBlock: 'latest' it returns [] and stops waiting for new events to show up right away, which was not case on when we are using watch().

Example-1 getPastEvents():

myContractInstance.getPastEvents('LogJob', {
    filter: {clusterAddress: [web3.eth.defaultAccount]},
    fromBlock: 1899162,
    toBlock: 'latest'
}, function(error, event){ console.log(event); });

Example-2 events.LogJob from web3.py guide: returns undefined

myContractInstance.events.LogJob({
    filter: {clusterAddress: [web3.eth.defaultAccount]},
fromBlock: 1899162
}, 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);

[Q] Is there any way to apply same approach like watch(); where if there is no event in between given fromBlock and toBlock: 'latest', then continue to watch and do not jump on to the next instruction.

Basically if an event returns []; I want the process keep watching new upcoming blocks and complete watching until the new event is emitted. Only solution comes to my mind is to make this call every 2 seconds until filter does not return [].

Best Answer

@Maxpeinas, that's correct, you have to use websocket provider in order to subscribe to events in web3.js 1.0 via myContract.events.MyEvent()

So, if you are using local TestRPC go with

const web3 = new Web3('ws://127.0.0.1:8545');

If you are using remote endpoint - change it to ws, for example - Infura already have working websocket endpoints for the main and the test networks, you can use them like this:

const web3 = new Web3('wss://ropsten.infura.io/ws');

I would guess that this will be the main 'problem' for developers which have used 0.2 with regular httpProvider and .watch(), since nowhere in the official web3.js 1.0 documentation for the event methods is not yet mentioned that you will need connect to websocket endpoint in order to subscribe for the EventEmitter.

If you are more experienced maybe you will be able to think of it, as the recommended provider in 1.0.0 docs is ws://127.0.0.1 instead of http://127.0.0.1, however there will be people that will wonder why their http event subscriber doesn't work.

Note: As opposed to myContract.events.myEvent(), you are able to use myContract.getPastEvents() with regular http provider with no problems, since it only fetches old logs and doesn't wait for new ones.

Related Topic