The Observer API

Overview
Take a one-minute rundown of the Observer API.
Observe
Observe operations on any object or array...
let obj = {};
...using the Observer.observe()
method.
Observer.observe(obj, mutations => {
mutations.forEach(mutation => {
console.log(mutation.type, mutation.name, mutation.path, mutation.value, mutation.oldValue);
});
});
Now changes will be delivered synchronously - as they happen.
Mutate
Programmatically make reactive changes using the Reflect-like set of operators...
Observer.set(obj, 'prop1', 'value1');
Observer.set(obj, {
prop2: 'value2',
prop3: 'value3',
});
...or switch to using object accessors - using the Observer.accessorize()
method...
Observer.accessorize(obj);
Observer.accessorize(obj, ['prop1', 'prop5', 'prop9']);
obj.prop1 = 'value1';
obj.prop5 = 'value5';
obj.prop9 = 'value9';
...or even go with a reactive Proxy of your object, and imply properties on the fly.
let _obj = Observer.proxy(obj);
_obj.prop1 = 'value1';
_obj.prop4 = 'value4';
_obj.prop8 = 'value8';
And no problem if you inadvertently cascade the approaches. No bizzare behaviours.
Observer.accessorize(obj, ['prop1', 'prop6', 'prop10']);
let _obj = Observer.proxy(obj);
Observer.set(_obj, 'prop1', 'value1');
Intercept
How about some level of indirection - the ability to hook into operators like Observer.set()
and Observer.deleteProperty()
to repurpose their operation? That's all possible using the Observer.intercept()
method!
Below, we catch any attempt to set an HTTP URL and force it to an HTTPS URL.
Observer.intercept(obj, 'set', (action, previous, next) => {
if (action.name === 'url' && action.value.startsWith('http:')) {
return next(action.value.replace('http:', 'https:'));
}
return next();
});
Now, only the first of the following will fly as-is.
Observer.set(obj, 'url', 'https://webqit.io');
Observer.set(obj, 'url', 'http://webqit.io');
Pass Some Detail to Observers
Operators, like Observer.set()
, can pass arbitrary value to observers via a params.detail
property.
Observer.set(obj, {
prop2: 'value2',
prop3: 'value3',
}, { detail: 'Certain detail' });
Observers will recieve this value in a mutation.detail
property.
Observer.observe(obj, 'prop1', mutation => {
console.log('An operation has been made with detail:' + mutation.detail);
});
Negotiate with Observers
Observers can access and act on a special object called the Response Object.
Observer.observe(obj, 'prop1', (mutation, event) => {
if (1) {
event.preventDefault();
} else if (2) {
event.stopPropagation();
} else if (3) {
event.waitUntil(new Promise);
}
});
Operators can access and honour the event's state.
let event = Observer.set(obj, {
prop2: 'value2',
prop3: 'value3',
}, { eventTypeReturn: true });
if (event.defaultPrevented) {
} else if (event.propagationStopped) {
} else if (event.promises) {
event.promises.then(() => {
});
}
Learn more about negotiation here
Clean Up Anytime
Need to undo certain bindings? There are the methods for that!
The End?
Certainly not! But this rundown should be a good start. Next:
Issues
To report bugs or request features, please submit an issue.
License
MIT.