Search code examples
javascriptreactjsethereumethers.jsdecentralized-applications

How to define listener argument for provider.on(eventName, listener) for listening a smart contract event with ethers.js?


I was following this quick guide to build a Dapp.

In order to build the user interface and interact with the smart contract, it uses React. There are the functions below:

async function submitBid(event) {
   event.preventDefault();
   if (typeof window.ethereum !== 'undefined') {
     const contract = await initializeProvider();
     try {
       // User inputs amount in terms of Ether, convert to Wei before sending to the contract.
       const wei = parseEther(amount);
       await contract.makeBid({ value: wei });
       // Wait for the smart contract to emit the LogBid event then update component state
       contract.on('LogBid', (_, __) => {
         fetchMyBid();
         fetchHighestBid();
       });
     } catch (e) {
       console.log('error making bid: ', e);
     }
   }
 }

 async function withdraw() {
   if (typeof window.ethereum !== 'undefined') {
     const contract = await initializeProvider();
     // Wait for the smart contract to emit the LogWithdrawal event and update component state
     contract.on('LogWithdrawal', (_) => {
       fetchMyBid();
       fetchHighestBid();
     });
     try {
       await contract.withdraw();
     } catch (e) {
       console.log('error withdrawing fund: ', e);
     }
   }
 }

According to ethers.js library, for listening a smart contract event it requires provider.on(eventName, listener), but I wonder why in this case for the listener argument it uses this (_) or (_, __), what does this mean to have each of them and why both are different if the callback function is pretty much the same for both functions, these are both smart contract's events to be considered:

event LogBid(address indexed _highestBidder, uint256 _highestBid);
event LogWithdrawal(address indexed _withdrawer, uint256 amount);

Solution

  • The general convention for naming a variable _ within a lamda function is to indicate that you are not going to be using the param that will be passed into the lamda but the consumer of the lamda still expects to pass in variables.

    That being said...javascript doesn't require you to do this and would actually work just fine if both listeners expected no arguments.

    It should be noted that the _ in

    contract.on('LogBid', (_, __) => {
             // _ is the unused param 'highestBidder'
             // __ is the unused param highest bid
             fetchMyBid();
             fetchHighestBid();
           }
    

    and the _ in

    contract.on('LogWithdrawal', (_) => {
           // _ is the address of who withdrawed
           // If lamda supplied another var it would hold the amount withdrawn
           fetchMyBid();
           fetchHighestBid();
         });
    

    are not the same value.