1

I have the following code

const broadcastTxn = await web3.eth
  .sendSignedTransaction(txn.signed)
  .on('receipt', (r) => console.log('Receipt', r))
  .on('confirmation', (c) => this.handleConfirmation(c, txn));

...

handleConfirmation(c: number, txn: Transaction): void {
  // do some stuff
}

I get multiple confirmations returned, but after the 3rd I'd like to cancel the callback/event that continues listening for .on('confirmation')

I tried putting logic in the handleConfirmation function to throw

handleConfirmation(c: number, txn: Transaction): void {
  // do some stuff
  if (c >= 3) throw new Error('cancelling callback');
}

but that doesn't work, it keeps getting called.

What is the correct way to end the .on('confirmation') listener?

es2017 & Node 14.9.0

hummmingbear
  • 2,294
  • 5
  • 25
  • 42
  • Does this answer your question? [JavaScript: remove event listener](https://stackoverflow.com/questions/4402287/javascript-remove-event-listener) – Thomas Sablik Mar 15 '21 at 07:10
  • @ThomasSablik thanks for the response. I wouldn't know what object to call `removeEventListener` on. I'm also not explicitly calling `addEventListener` I'm chaining a `.on(..)` function. – hummmingbear Mar 15 '21 at 07:13
  • Usually on the same object you added the event. Sometimes you have to break call chains and store objects in variables. – Thomas Sablik Mar 15 '21 at 07:14
  • `await web3.eth.sendSignedTransaction(txn.signed).removeEventListener('confirmation')` does not work unfortunately – hummmingbear Mar 15 '21 at 07:15
  • This creates a new object without events. You have to remove the events from the object to added the events. In Node.js it's `off` or `removeListener`: https://nodejs.org/api/events.html – Thomas Sablik Mar 15 '21 at 07:16
  • That _sounds_ right however I'm not sure how to implement it in my case. Care to post an example? – hummmingbear Mar 15 '21 at 07:17
  • You have to break your call chain after `sendSignedTransaction(txn.signed)` and store it in a variable. Here is another link https://stackoverflow.com/questions/23893872/how-to-properly-remove-event-listeners-in-node-js-eventemitter# – Thomas Sablik Mar 15 '21 at 07:19
  • @ThomasSablik If I do `const broadcastTxn = await web3.eth.sendSignedTransaction(txn.signed)` I am unable to call `broadcastTxn.on('...')` - it throws and error. I get what you're pointing at but it is unclear to me how I can store that variable so I can reference it – hummmingbear Mar 15 '21 at 07:23

1 Answers1

0

@ThomasSablik pointed me in the correct direction. I needed to capture the object without using await. Then I could reference it and use await afterwards. Solution below

const signedTxnListener = web3.eth
  .sendSignedTransaction(txn.signed)
  .on('receipt', (r) => console.log('Receipt', r))
  .on('confirmation', (c) => this.handleConfirmation(c, txn));

await signedTxnListener
...

handleConfirmation(c: number, txn: Transaction): void {
  // do some stuff
  if (c >= 3) signedTxnListener.off('confirmation');
}
hummmingbear
  • 2,294
  • 5
  • 25
  • 42