Observable API provides the whole life cycle of object observation functionality.
Additionally, this API defines the Change object, list of which being a parameter of an observer callback function.
object-observerprovidesObservabletop level object as a named import:import { Observable } from 'object-observer.js'
-
input is a non-null object; returns input's clone, decorated with an
Observableinterface- clone is deep
- nested objects are turned into
Observableinstances too - cloning performed only on own enumerable properties, leaving a possibility to 'hide' some data from observation
-
options is an object, optional; may include any of these:
async: boolean, defaults tofalse, controls the sync/async fashion of changes delivery; details hereThis flag will affect all observers of this
Observable
let person = {
name: 'Aya',
age: '1',
address: {
city: 'city',
street: 'street'
}
},
observablePerson;
observablePerson = Observable.from(person);- input is a non-null object; returns
trueif it stands for implementation ofObservableAPI as it is defined here
Observable.isObservable({}); // false
Observable.isObservable(observablePerson); // true
Observable.isObservable(observablePerson.address); // trueobservableMUST be an instance ofObservable(seefrom)- callback is a function, which will be added to the list of observers subscribed for a changes of this observable; changes delivered always as a never-null-nor-empty array of
Changeobjects; each change is a defined, non-null object, seeChangedefinition below - options is an object, optional
function personUIObserver(changes) {
changes.forEach(change => {
console.log(change.type);
console.log(change.path);
console.log(change.value);
console.log(change.oldValue);
});
}
...
// following the observablePerson example from above
Observable.observe(observablePerson, personUIObserver, options); // options is optional
const observableAddress = observablePerson.address;
Observable.observe(observableAddress, personUIObserver); // nested objects are observables too
observablePerson.address = {}; // see belowAttention! Observation set on the nested objects, like
addressin the example above, 'sticks' to that object. So if one replaces the nested object of the observable graph (see the last line of code above), observer callbacks are NOT moved to the new object, they stick to the old one and continue to live there - think of detaching/replacing a sub-graph from the parent.
observableMUST be an instance ofObservable(seefrom)- receives a function/s which previously was/were registered as an observer/s and removes it/them. If no arguments passed, all observers will be removed.
Observable.unobserve(observablePerson, personUIObserver);
// or
Observable.unobserve(observablePerson);
// same applies to the nested
Observable.unobserve(observableAddress);If/When provided, options parameter MUST contain ONLY one of the properties below, no 'unknown' properties allowed.
In order to fail-fast and prevent unexpected mess down the hill, incorrect observation options will throw.
-
path- non-empty string; specific path to observe, only a changes of this exact path will be notified; details here -
pathsOf- string, MAY be empty; direct properties of the specified path will be notified; details here -
pathsFrom- non-empty string, any changes from the specified path and deeper will be delivered to the observer; details here
type- one of the following:insert,update,delete,shuffleorreversepath- path to the changed property represented as an Array of nodesvalue- new value;undefinedindelete,shuffleandreversechangesoldValue- old value;undefinedininsert,shuffleorreversechangesobject- an immediate subject of change, property of which has been changed (ES6 module distro ONLY)