Skip to content

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` 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 was
rx.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.