How to unregister from ipcRenderer.on event listener?

Kode_12 picture Kode_12 · Aug 8, 2019 · Viewed 7k times · Source

In my host application I have a button, that when clicked, sends data over to my angular application with data. Like so:

<button (click)="onClick()">Send Some Data</button>

component:

onClick() {  
ipcRenderer.send("data-bridge",{name: 'John Smith', address: 'Main Street', date: new Date() );
}

In my angular application I am receiving data like so:

import { ElectronService } from 'ngx-electron';

export class AppComponent {
  constructor( private electronService: ElectronService) {}

   ngOnInit() {
    if (this.electronService.ipcRenderer) {

      this.electronService.ipcRenderer.on('data-bridge', (event, data) => {
            console.log('got something', data)
        })
    }
  }
}

The behavior that I noticed was that for x time I click the button, I will see the alert x amount of times:

  • 1 click --> 1 alert
  • 2 click --> 2 alerts
  • 3 click --> 3 alerts.. etc etc

So this obviously indicated to me that there is a memory leak. The solution is straightforward, remove the event listener after it receives an event.

I have tried doing something like:

this.electronService.ipcRenderer.on('data-bridge', (event, data) => {
        alert('got something');
        this.electronService.ipcRenderer.removeAllListeners()
}

But the multiple alerts still happens on a single click.

I cannot use the ipcRenderer.once method, since I need the listener to remain open, just not have multiple listeners of the same. How can I remove the ipcRenderer.on('data-bridge', ...) event listener, so that for every click of the button, I will only have one event listener?

Answer

pergy picture pergy · Aug 9, 2019

ipcRenderer is an EventEmitter class, so you have removeListener(eventName, listener) (or off) method on it.

This should work

// on construct
this.onData = (event, data) => {
  console.log('got something', data)
})
// on init
ipcRenderer.on('data-bridge', this.onData)
// on deconstruct
ipcRenderer.removeListener('data-bridge', this.onData)