reactive-property

1.0.0 • Public • Published

reactive-property

A small library for getter-setter functions that react to changes.

NPM NPM Build Status

The pattern for creating reusable data visualizations described in Towards Reusable Charts is great. However, the boilerplate code for getter-setter functions is a bit cumbersome. This library creates chainable getter-setter functions so you don't have to. For more information, see "Introducing reactive-property" on Medium.

Here's a code example from Towards Reusable Charts showing the general pattern with width and height as example chainable getter-setters.

function chart() {
  var width = 720, // default width
      height = 80; // default height
 
  function my() {
    // generate chart here, using `width` and `height`
  }
 
  my.width = function(value) {
    if (!arguments.length) return width;
    width = value;
    return my;
  };
 
  my.height = function(value) {
    if (!arguments.length) return height;
    height = value;
    return my;
  };
 
  return my;
}

Here's how the above code can be transformed when using reactive-property.

function chart() {
 
  function my() {
    // generate chart here, using `my.width()` and `my.height()`
  }
 
  my.width = ReactiveProperty(720);
  my.height = ReactiveProperty(80);
 
  return my;
}

Pros:

  • You don't need to write the getter-setter boilerplate.

Cons:

  • You'll have one more dependency.
  • You'll need to access values via getters (my.width() instead of simply width).

For more detailed example code, have a look at the tests.

Installing

If you are using NPM, install the library by running this command.

npm install reactive-property

Require it in your code like this.

var ReactiveProperty = require("reactive-property");

You can also require the script in your HTML like this.

<script src="//datavis-tech.github.io/reactive-property/reactive-property-v0.9.0.js"></script>

Or use the minified version.

<script src="//datavis-tech.github.io/reactive-property/reactive-property-v0.9.0.min.js"></script>

Try reactive-property in your browser.

API Reference

Creating Properties

# ReactiveProperty([defaultValue])

Create a property by invoking ReactiveProperty as a constructor function.

var reactiveProperty = ReactiveProperty();

If defaultValue is specified, it is set as the default value of the property. This value can be any type.

var a = ReactiveProperty(3); // The default value is 3.

Accessing Properties

# reactiveProperty([value])

If value is specified, sets the value of the property. Returns the context object for method chaining.

a(5);

If value is not specified, returns the value of the property.

a(); // Returns 5

# reactiveProperty.default()

Returns the defaultValue specified in the constructor. If, defaultValue was not specified in the constructor, then the default function is not defined.

The expected usage pattern is to always check if default is defined before invoking it, like this.

if(a.default){
  console.log(a.default());
}

Method Chaining

Set up chainable setters by using a context object (called my in this example).

var my = {
  x: ReactiveProperty(5),
  y: ReactiveProperty(10)
};
my.x(50).y(100); // Chainable setters.

You can also set up properties this way.

var my = {};
my.x = ReactiveProperty(5);
my.y = ReactiveProperty(10);
my.x(50).y(100);

Listening for Changes

# reactiveProperty.on(listener)

Listens for changes in the property value. Returns listener.

The listener callback function will be invoked synchronously when the property value is set. If the property has a default value that is not undefined, then listener is invoked immediately. The special value null is considered a defined value and is passed into listeners, whereas setting a property value to undefined does not cause the listener to be invoked.

Arguments to the callback function - listener(value, oldValue)

  1. value the current value of the property.
  2. oldValue the previous value (may be undefined if the value was not previously set).
a.on(function(value, oldValue){
  console.log("The value of 'a' changed from " + oldValue + " to " + value);
});

# reactiveProperty.off(listener)

Removes the given listener function that was previously added with on.

function listener(){
  console.log("'a' changed!");
}
a.on(listener);
a.off(listener);
a(5); // The listener is NOT called.

Since listener is returned from on, the following pattern also works.

var listener = a.on(function (){
  console.log("'a' changed!");
});
a.off(listener);
a(5); // The listener is NOT called.

# reactiveProperty.destroy()

Removes all listeners previously added with on. Use this to avoid memory leaks in cases where you know properties will no longer be used.

a.on(function (){ console.log("'a' changed!"); });
a.on(function (){ console.log("'a' really changed!"); });
a.destroy(); // Removes all listeners.
a(5); // No listeners are called.

Comparison to Similar Libraries

Reactive-model performs pretty well as compared to other implementations of the Observer and Event Emitter patterns.

screen shot 2016-05-11 at 4 12 53 pm

Data from benchmarks by @Hypercubed, found at Hypercubed/EventsSpeedTests node-v4.4.4.

Similar Libraries:

Dependencies (0)

    Dev Dependencies (1)

    Package Sidebar

    Install

    npm i reactive-property

    Weekly Downloads

    0

    Version

    1.0.0

    License

    MIT

    Last publish

    Collaborators

    • curran