How can I stop listening to BroadcastChannel

1.6k Views Asked by At

I created this broadcast service. How can I add the BroadcastChannel.removeEventListener method when the event handler for addEventListener is dynamically generated?

@Injectable({
  providedIn: 'root'
})
export class BroadcastService {
  private consumer: BroadcastChannel;
  private producer: BroadcastChannel;

  constructor() {
    this.consumer = new BroadcastChannel('pluginGlobalEventBus');
    this.producer = new BroadcastChannel('pluginGlobalEventBus');
  }

  /**
   * broadcast a message
   */
  postMessage(message: any): void {
    this.producer.postMessage(message);
  }

  /**
   * listen to a broadcast
   */
  addEventListener(eventName, listener): void {
    this.consumer.addEventListener('message', event => {
      if (event.data.name === eventName) {
        listener(event.data.value);
      }
    });
  }

  /**
   * stop broadcasting
   */
  close(): void {
    this.consumer.close();
    this.producer.close();
  }
}
2

There are 2 best solutions below

0
On

You can store event listeners in a private array and iterate on those listeners to remove them.

private eventListeners = [] // To store event listeners generated dynamically

addEventListener(eventName, listener): void {
    const eventListener = event => {
      if (event.data.name === eventName) {
        listener(event.data.value);
      }
    };
    this.consumer.addEventListener('message', eventListener);
    this.eventListeners.push(eventListener); // Store event listener
}

removeEventListener() {
  // Iterate through all stored event listeners to remove them
  this.eventListeners.forEach((listener) => {
    this.consumer.removeEventListener('message', listener); 
  });
  // Do not forget to clear listeners array
  this.eventListeners = [];
}

If for some reason, you need to remove only one listener at a time, then I guess you can use a Map to store event listener instead, and generate a unique id on addEventListener.

0
On

Its pretty simple:

// Connect to a channel
var bc = new BroadcastChannel('test_channel');

// More operations (like postMessage, …)

// When done, disconnect from the channel
bc.close();