capacitor icon indicating copy to clipboard operation
capacitor copied to clipboard

feat: removing a single event listener / `Plugin#removeListener`

Open buschtoens opened this issue 4 years ago • 5 comments

Feature Request

Description

Allow removing listeners on plugins selectively, instead of just removeAllListeners().

Platform(s)

Android, iOS, web

Preferred Solution

Add a removeListener(eventName: string, listenerFunc: ListenerCallback) method to all plugins that support addListener. The removeListener method already exists as private API on WebPlugin.

It expects an eventName and a stable listenerFunc reference. If the given pair is not currently registered, it no-ops.

Bonus points for adding { once: boolean } as an option to addListener.

Additional Context

https://github.com/ionic-team/capacitor/blob/a37e188bf1ab57465e86f6b2ab7c4c2308a21173/core/src/web/index.ts#L83-L108

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

buschtoens avatar Nov 19 '20 17:11 buschtoens

Would this existing mechanism meet your needs? (Example In TypeScript)

const myPluginEventListener = Plugins.MyPlugin.addListener(
  'myPluginEvent',
  (info: any) => {
    console.log('myPluginEvent was fired');
  },
);

myPluginEventListener.remove();

See "Plugin Events" in: https://capacitorjs.com/docs/plugins/ios https://capacitorjs.com/docs/plugins/android

JMCollins avatar Nov 22 '20 17:11 JMCollins

omg yes of course. I somehow didn't see this, sorry. 🤦🏼‍♂️

Anyhow though, many JS libraries expect the standard EventTarget interface. Would you be open to a PR implementing it in addition?

buschtoens avatar Nov 22 '20 19:11 buschtoens

I am a first-time Capacitor user (not on the dev team). I am currently working on a plugin and happened to see your post while doing some research. Glad I could be helpful. Cheers.

JMCollins avatar Nov 22 '20 20:11 JMCollins

Would this existing mechanism meet your needs? (Example In TypeScript)

const myPluginEventListener = Plugins.MyPlugin.addListener(
  'myPluginEvent',
  (info: any) => {
    console.log('myPluginEvent was fired');
  },
);

myPluginEventListener.remove();

See "Plugin Events" in: https://capacitorjs.com/docs/plugins/ios https://capacitorjs.com/docs/plugins/android

Thank you @JMCollins! This helped me out a lot tonight :)

gbrits avatar Mar 18 '21 18:03 gbrits

It seems like this issue could be closed.

pchasco avatar May 18 '22 16:05 pchasco

capacitor v4

hm.. but altho the

myPluginEventListener.remove();

says it succeeded, i add a listener again and now get duplicate events stop, remove listener add listener again,

now get tripple... etc

ionic vue, add on activity, stop on view exit (ionviewWillLeave) I see the debug that says it was called, I use .then() and it returns to the then but as the view exits, the variable holding the listener is reset on view re-enter, so I don't know its already set..

but remove didn't

on ionViewDidEnter() {

          EstimoteUWBPlugin.addListener('UWBInfo', (eventData) => this.UWBInfoHandler(eventData)).then(listenerHandle => {
            this.UWBListener = listenerHandle;
log 
     To Native ->  sduwb addListener 60012300

on ionViewWillLeave(){

     this.UWBListener.remove().then(() => {
... log 
  To Native ->  sduwb removeListener 60012302
     because I got this log entry, it says that the addListener returned the listener object, cause I was able to call remove successfully

looks like the number is a sequence number, each plugin call increments by 1

plugin only used in this view

sdetweil avatar Jan 14 '23 15:01 sdetweil

Hello! what if the pluginEvent is situated in mounted(). how do you get a reference to it to issue the remove()/removeListener() for capacitor.ios? I'm using Quasar

michael-lau1982 avatar Aug 21 '23 11:08 michael-lau1982

Closing since the addListener returns a remove function you can use to remove that specific listener.

Note that the previous comment that mentioned this is out of date, the correct syntax would be using await, like this:

const myPluginEventListener = await MyPlugin.addListener(
  'myPluginEvent',
  (info: any) => {
    console.log('myPluginEvent was fired');
  },
);

myPluginEventListener.remove();

jcesarmobile avatar Feb 01 '24 13:02 jcesarmobile

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.

ionitron-bot[bot] avatar Mar 02 '24 14:03 ionitron-bot[bot]