/bacon-unsub

Unsubscribe from BaconJS observables through delegate methods

Primary LanguageJavaScript

NPM version

Unsubscribe from observables through delegate methods.

Using Bacon with traditional Object Oriented frameworks can be hard. These frameworks typically rely on methods with side effects. Take Backbone for example. When the remove() method is called you often want to stop your running observables. This involves saving reference to each unsubscribe method returned from onValue, onError, onEnd or subscribe and then calling each. This is tedious; bacon-unsub to the rescue.

Bacon-unsub is a small utility module that augments Bacon's onValue, onError onEnd, and subscribe methods with an unsubOn method that automatically unsubscribes the observable from the source whenever that method is called.

Install

$ npm install --save bacon-unsub

Usage

var Bacon = require('baconjs');

// Augments Bacon subscription methods with the 'unsubOn' method
require('bacon-unsub')(Bacon);

// Mock object that has a destroy method
var frameworkObject = {
	destroy: () => console.log('Framework Destroy')
};

// Repeat numbers until unsubscribed
Bacon.repeatedly(200, [1,2,3,4,5])
    .onValue(value => console.log('Value:', value))
    .unsubOn(frameworkObject, 'destroy');

// Call the delegate method after 2 seconds.
// Values are no longer printed after 'Framework Destroy'.
setTimeout(() => frameworkObject.destroy(), 2000);

Multiple unsubOn calls pointing to the same delegate method will all get unsubscribed when the delegate is called.

Bacon.repeatedly(200, [1,2,3,4,5])
    .onValue(value => console.log('# Value:', value))
    .unsubOn(frameworkObject, 'destroy');

Bacon.repeatedly(200, ['foo', 'bar'])
    .onValue(value => console.log('String Value:', value))
    .unsubOn(frameworkObject, 'destroy');

setTimeout(() => frameworkObject.destroy(), 2000);

The following example integrates with Backbone. When the Backbone.View.remove method is called the subscription created in the initialize method is automatically unsubscribed.

var Bacon = require('baconjs');
require('bacon-unsub')(Bacon);

var FooView = Backbone.View.extend({
    initialize: function() {
		var el = this.el;

		// Update our view every 200ms with a new value until unsubscribed.
        Bacon.repeatedly(200, [1,2,3,4,5])
            .onValue(value => {
                console.log('Value:', value);
                el.innerText = value;
            })
            .unsubOn(this, 'remove');
    },

    remove: function() {
        console.log('Removed!');
    }
});

// Create the view and append it to the dom.
var view = new FooView();
document.body.appendChild(view.el);

// Remove it after 2 seconds.
setTimeout(() => view.remove(), 2000);

License

MIT © Paul LeMarquand