proxy-observable
ES6 Proxy observable implementation. Supports Arrays and Objects
Attention!
Please keep in mind that the implementation is based on ES6 Proxy feature which is a very slow thingy
Install
npm install proxy-observable --save
Usage
Just call observable()
if you want an object or an array to be observable
import observable from "proxy-observable";
const soldier = {
name: "Titus Pullo",
age: 36,
inventory: observable({
sword: "Dagger",
coins: 0
}),
friends: observable(["Gaius Octavian"])
};
console.log(JSON.stringify(soldier, null, 2));
{
"name": "Titus Pullo",
"age": 36,
"inventory": {
"sword": "Dagger",
"coins": 0
},
"friends": [
"Gaius Octavian"
]
}
Object
const onCoinsChanged =
soldier.inventory.on("coins", (value, prev) => {
console.log(value, prev); // 100 0
});
soldier.inventory.coins = 100; // onCoinsChanged will be called
soldier.inventory.off(onCoinsChanged);
Simply speaking soldier.inventory
is still just a simple object, but it has additionally a few things:
- method
on
Attach a handler to an event for the elements - method
once
Attach a handler to an event for the elements. The handler is executed at most once per element per event type - method
off
Remove an event handler - you can call just
soldier.inventory.newProp = value
to define a new prop, instead ofsoldier.inventory["newProp"] = value
Array
soldier.friends.on("change", item => {
console.log(item); // "Lucius Vorenus" twice
});
soldier.friends.on("shift", item => {
console.log(item); // "Gaius Octavian"
});
soldier.friends.push("Lucius Vorenus");
soldier.friends[0] = "Lucius Vorenus"
soldier.friends.shift();
soldier.friends
is still just a simple array with on
, once
and off
methods and predefined events
Array events
change
- Fires when an item in an array is changed:
arr[0] = "new value";
// or
arr.push("new value");
pop
- Fires when pop
method is called:
arr.pop();
shift
- Fires when shift
method is called:
arr.shift();
any other Array's methods
any
event
Do you want to track all the events? Just use any
like this:
// object
soldier.inventory.on("any", (value, prev, prop) => {
console.log(prop); // "coins", "shield"
});
soldier.inventory.coins = 1000;
// This way you can track when a new property is added to an object
soldier.inventory.shield = "Gold Shield";
// array
soldier.friends.on("any", (value, prev, e) => {
// e is "change", "pop", "shift" or any other method of Array
console.log(e);
});
soldier.friends[0] = "Mark Antony";
soldier.friends.pop();
Browser Usage
<!-- ES6 not minified version -->
<script src="../node_modules/proxy-observable/bin/proxy.observable.es6.js"></script>
<!-- ES5 minified version -->
<!--<script src="../node_modules/proxy-observable/bin/proxy.observable.min.js"></script>-->
<script>
const soldier = {
name: "Titus Pullo",
age: 36,
inventory: observable({
sword: "Dagger",
coins: 0
})
};
console.log(soldier.inventory.coins); // 0
soldier.inventory.on("coins", (value, prev) => {
console.log(value, prev); // 100 0
});
soldier.inventory.coins = 100;
</script>
One more example
const Frodo = observable({
name: "Frodo Baggins",
bag: observable([]),
friends: observable([])
});
const Samwise = {
name: "Samwise Gamgee",
friends: [Frodo]
};
Frodo.friends.on("change", friend => {
console.log(`Frodo has a new friend ${friend.name}! Cograts!`);
});
Frodo.bag.on("any", (item, prev, e) => {
if (e === "change") {
console.log("Frodo got a new item: " + item);
if (item === "ring") {
console.log("Oh! My Precious!");
}
} else if (e === "pop" || e === "shift"){
console.log("Frodo lost an item: " + item);
if (item === "ring") {
console.log("Gollum! I'm coming to get you!");
}
}
});
Frodo.friends.push(Samwise);
Frodo.bag.push("apple");
Frodo.bag.push("ring");
Frodo.bag.pop();
Frodo.friends.pop();
API
ctx
observable(ctx) => Makes an object or array observable
Returns: object|array
- Observable object or array
Param | Type | Description |
---|---|---|
ctx | object|array |
Input Object or Array |
callback
observable.on(e, callback) => Subscribes on event (property changed)
Returns: function
- Input callback for unsubscribing
Param | Type | Description |
---|---|---|
e | string |
Event name or property name |
callback | function |
Callback |
Callback signature
(value, prev, e) => {}
Param | Type | Description |
---|---|---|
value | any |
Current value |
prev | any |
Previous value |
e | string |
Event name or property name |
callback
observable.once(e, callback) => Subscribes once. The handler is executed at most once per element per event type
Returns: function
- Input callback for unsubscribing
Param | Type | Description |
---|---|---|
e | string |
Event name or property name |
callback | function |
Callback |
boolean
observable.off(callback) => Removes event handler
Returns: boolean
- True if unsubscribed
Param | Type | Description |
---|---|---|
callback | function |
Callback |
ES6 JavaScript Proxy MDN documentation
godban
Browsers support made byIE / Edge |
Firefox |
Chrome |
Safari |
Opera |
iOS Safari |
Chrome for Android |
---|---|---|---|---|---|---|
Edge | last 3 versions | last 10 versions | last 5 versions | last 4 versions | last 2 versions | last 3 versions |
License
MIT