---
heading: 'Event Emitter'
title: 'Simple Event-Emitter/PubSub pattern'
date: '2021-09-06'
icon: 'Javascript'
draft: false
summary: 'A lightweight pub/sub mechanism to handle custom events without adding a full-blown library.'
tags: ['javascript', 'pattern', 'event-emitter', 'pubsub']
---

Simple Event Emitter or PubSub pattern <Twemoji emoji="owl" />

```js:event-emitter.js showLineNumbers
class Event {
  constructor() {
    this.events = {}
  }

  subscribe(event, handler) {
    this.events[event] = this.events[event] || []
    this.events[event].push(handler)
    return () => this.unSubscribe(event, handler)
  }

  unSubscribe(event, handler) {
    let handlers = this.events[event]
    if (handlers && Array.isArray(handlers)) {
      for (let i = 0; i < handlers.length; i++) {
        if (handlers[i] === handler) {
          handlers.splice(i, 1)
          break
        }
      }
    }
  }

  emit(event, ...args) {
    ;(this.events[event] || []).forEach((handler) => {
      handler(...args)
    })
  }
}
```

Usage

```js:main.js showLineNumbers
// Create a global instance in your app
let globalEvent = new Event()

let handler1 = (data) => console.log(`handler1(): FOO event emiited with data: ${data}`)
let handler2 = (data) => console.log(`handler2(): FOO event emiited with data: ${data}`)

// Subscribe to event
globalEvent.subscribe('FOO', handler1)
globalEvent.subscribe('FOO', handler2)

// Emit event when needed
globalEvent.emit('FOO', 'foo')

// Expected:
// handler1(): FOO event emiited with data: foo
// handler2(): FOO event emiited with data: foo

// Unsubscribe event
globalEvent.unSubscribe('FOO', handler2)

// Then
globalEvent.emit('FOO', 'bar')

// Expected:
// handler1(): FOO event emiited with data: bar
```
