Creating from objects
From.object wraps an object, emitting finely-grained updates when changes are made to it. This can be useful to maintaining a ‘shape’ of data and using just one reactive instead of making lots of reactives for each property of an object.
const rx = Rx.From.object({ name: `bob`, level: 2, colour: `red` });rx.onValue(changed => { // Change happened});rx.set({ name: `mary`, level: 3, colour: `red` });
// `onValue` handler will get called, with `changed` having a value of:// { name: `mary`, level: 3, colour: `red` }
It’s important that you manipulate the wrapped object using the provided set
, update
and updateField
functions rather than manipulating the original object.
With set
you have to provide a complete object with the same shape as the original.
update
‘patches’ the object with a partial set of key-value pairs, overwriting what’s already there.
// Update 'name' and 'colour' fields, leaving// 'level' as it wasrx.update({ name: `john`, colour: `green` });
updateField
sets a single field:
rx.updateField(`level`, 2);
The onValue
event always emits the whole object. There are two additional event handlers, onDiff
& onField
. onDiff
emits a change set rather than whole object. This allows the event listener to get fine-grained information on what field has changed and how. For example:
rx.onDiff(diff => { })rx.updateField(level, 12);// Emits the diff:// { path: `level`, value: 2, previous: 12, state: `changed` }
onField
allows subscribing to particular field changes.
rx.onField(`colour`, {fieldName, pattern, value} => { // Only get fires when 'colour' property changes // 'fieldName' is the property that changed, // 'pattern' will be the original subscription pattern and // 'value' is the new value of the field.})
Object proxy
An alternative to From.object
is From.objectProxy . In this case, a proxy of the source object is created such that changes made on the proxy flow through and are emitted from the reactive. This can be useful if you want a reactive object to interoperate with other parts of code that shouldn’t know anything about reactives.
const { proxy, rx } = Rx.From.objectProxy({ colour: `red`, x: 10, y: 20 });rx.onValue(v => { // Notified when object changes});
The proxy object appears to be the same as the input object: { colour: 'red', x: 10, y: 20 }
. But if we change fields, the reactive will magically pick it up and emit change events.
// Will cause the rx.onValue handler to fire...proxy.colour = `pink`;
Keep in mind only change made via the proxy object returned by objectProxy
will make the magic happen.
A twist on From.objectProxy
is From.objectProxySymbol . This returns the reactive as symbol on the original object, rather than returning the proxy and the reactive.
const person = Rx.fromProxySymbol({name: `marie` });person.name = `blah`;person[Rx.symbol].on(msg => { // Value changed...});
This can be more ergonomic because you don’t need to juggle two return values, the proxied object and the stream.