keychange event

The keychange event is dispatched on live variables wrapping an object, when keys are created or deleted.

The event does not fire when a key's value changes (only if it is new or deleted), and therefore is not suitable for listening to all changes to a live variable. Use the change event for that instead.

Warning: This is a low-level API. In most cases, there are more ergonomic alternatives available, such as directly passing a live variable to Object.keys() in an effect().

Syntax

when($live).keychanges().then(event => { // … }); $live.addEventListener('keychange', event => { // … });

Event details

The event fires only on objects, when new keys are added, or existing ones are deleted. Non-objects (and null) are considered not to have any keys. Functions are considered objects and may have keys. More specifically, an instanceof Object test determines whether the value's keys are observed. This is to avoid unexpected behavior like character indexes on strings being included in the key diffing (which could be a big performance hit for large strings).

The event, like Object.keys(), does not consider symbols; adding or removing symbols from an object never triggers the keychange event.

The keychange event exposes some details under the event.detail property:

event.detail.keys
An array of string keys that were deleted or created on the object wrapped by the live variable.

Examples

Object.keys()

The keychange event mostly exists for internal purposes and is rarely useful outside of that. Specifically, it is used for live variables to properly react to iteration and other such operations.

So, for this example, let's do something a bit inefficient for the sake of learning. We'll take one live variable wrapping an object, and then have another live variable keep track of the object's keys. We'll use live.link() to make sure they stay in sync.

const $ = live({ object: { foo: 23, bar: -7 } }); live.link($.$keys, { get: () => Object.keys($.object), changes: when($.$object).keychanges() });

Now, when the object sees a key getting removed or added (and only then), the live.link() will update. If we, on the other hand, use the change event instead, then the link would update much more often than necessary, which would be inefficient. The reason keychange is generally not needed is because its use-case is almost entirely covered by Yozo internals; the above could be rewritten to

const $ = live({ object: { foo: 23, bar: -7 } }); live.link($.$keys, () => Object.keys($.$object));

This also uses the keychange event under the hood, but is abstracted away and therefore (presumably) a bit easier to think about.

See also