Home > other >  Trigger an event when an object is added to a Map or Set
Trigger an event when an object is added to a Map or Set

Time:03-23

I'm looking for a way to trigger an event when an object is added to a Map or Set? Something like this, is it possible? Right now we're just using a timer to check.

let mymap = new Map() // or Set()
mymap.on('set', obj => {
    console.log(obj) 
}

This is my first pass based on @PsychoX's recommendations, thoughts?

const EventEmitter = require('events')
const emitter = new EventEmitter()

const Wrapper = () => {
    this._set = new Set()
    this.get = key => { return this._set.get(key) }
    this.add = obj => {
        this._set.add(obj)
        emitter.emit('add', obj)
    }
    this.values = () => { return this._set.values() }
}

emitter.on('add', obj => {
    console.log('added', obj)
})

let test = new Wrapper()
test.add({hello:'world'})

CodePudding user response:

You can extend the default Map or use proxy.

My approach:

class ObservableMapChangeEvent extends Event {
    constructor(observable, key, oldValue, newValue) {
        super('change');
        this.observable = observable;
        this.key = key;
        this.oldValue = oldValue;
        this.newValue = newValue;
    }
}

class ObservableMap extends Map {
    constructor(iterable) {
        super(iterable);
        this._eventTarget = new EventTarget();
    }

    on(name, listener, options) {
        this._eventTarget.addEventListener(name, listener, options);
    }

    off(name, listener, options) {
        this._eventTarget.addEventListener(name, listener, options);
    }

    delete(key) {
        this._eventTarget.dispatchEvent(new ObservableMapChangeEvent(this, key, this.get(key), undefined));
        super.delete(key);
    }
    set(key, value) {
        this._eventTarget.dispatchEvent(new ObservableMapChangeEvent(this, key, this.get(key), value));
        super.set(key, value);
    }
}

// Example:
const foo = new ObservableMap();
foo.on('change', event => {
    console.log(`Changes [${event.key}] to '${event.newValue}' (old: '${event.oldValue}')`);
});
foo.set('hello', 'world'); // Changes [hello] to 'world' (old: undefined)

You might want to look at:

  • Related