LiveMap

LiveMap is a key/value data structure that synchronizes its state across users in realtime. It enables you to store primitive values, such as numbers, strings, booleans and buffers, as well as other objects, enabling you to build complex, hierarchical object structure.

Conflicts in a LiveMap are automatically resolved with last-write-wins (LWW) semantics. The latest received operation on a key will be applied to the LiveMap and broadcast to all clients.

A LiveMap instance can be created using the channel.objects.createMap() method. It must be stored inside another LiveMap object that is reachable from the root object .

channel.objects.createMap() is asynchronous, as the client sends the create operation to the Ably system and waits for an acknowledgment of the successful map creation.

JavaScript v2.9
const map = await channel.objects.createMap(); await root.set('myMap', map);
Copied!

Optionally, you can specify an initial key/value structure when creating the map:

JavaScript v2.9
// Pass a regular JavaScript object reflecting the initial state const map = await channel.objects.createMap({ foo: 'bar', baz: 42 }); // You can also pass other objects as values for keys await channel.objects.createMap({ nestedMap: map });
Copied!

Get the current value for a key in a map using the LiveMap.get() method:

JavaScript v2.9
console.log('Value for my-key:', map.get('my-key'));
Copied!

You can subscribe to data updates on a map to receive realtime changes made by you or other clients.

Subscribe to data updates on a map using the LiveMap.subscribe() method:

JavaScript v2.9
map.subscribe((update) => { console.log('Map updated:', [...map.entries()]); console.log('Update details:', update); });
Copied!

The update object provides details about the change, listing the keys that were changed and indicating whether they were updated (value changed) or removed from the map.

Example structure of an update object when the key foo is updated and the key bar is removed:

{ { "foo": "updated", "bar": "removed" } }
Copied!

Use the unsubscribe() function returned in the subscribe() response to remove a map update listener:

JavaScript v2.9
// Initial subscription const { unsubscribe } = map.subscribe(() => console.log('Map updated')); // To remove the listener unsubscribe();
Copied!

Use the LiveMap.unsubscribe() method to deregister a provided listener:

JavaScript v2.9
// Initial subscription const listener = () => console.log('Map updated'); map.subscribe(listener); // To remove the listener map.unsubscribe(listener);
Copied!

Use the LiveMap.unsubscribeAll() method to deregister all map update listeners:

JavaScript v2.9
map.unsubscribeAll();
Copied!

Set a value for a key in a map by calling LiveMap.set(). This operation is synchronized across all clients and triggers data subscription callbacks for the map, including on the client making the request.

Keys in a map can contain numbers, strings, booleans and buffers, as well as other LiveMap and LiveCounter objects.

This operation is asynchronous, as the client sends the corresponding update operation to the Ably system and waits for acknowledgment of the successful map key update.

JavaScript v2.9
await map.set('foo', 'bar'); await map.set('baz', 42); // Can also set a reference to another object const counter = await channel.objects.createCounter(); await map.set('counter', counter);
Copied!

Remove a key from a map by calling LiveMap.remove(). This operation is synchronized across all clients and triggers data subscription callbacks for the map, including on the client making the request.

This operation is asynchronous, as the client sends the corresponding remove operation to the Ably system and waits for acknowledgment of the successful map key removal.

JavaScript v2.9
await map.remove('foo');
Copied!

Iterate over key/value pairs, keys or values using the LiveMap.entries(), LiveMap.keys() and LiveMap.values() methods respectively.

These methods return a map iterator object for convenient traversal. Note that contrary to JavaScript’s Map counterpart, these methods do not guarantee that entries are returned in insertion order.

JavaScript v2.9
for (const [key, value] of map.entries()) { console.log(`Key: ${key}, Value: ${value}`); } for (const key of map.keys()) { console.log(`Key: ${key}`); } for (const value of map.values()) { console.log(`Value: ${value}`); }
Copied!

Subscribe to lifecycle events on a map using the LiveMap.on() method:

JavaScript v2.9
map.on('deleted', () => { console.log('Map has been deleted'); });
Copied!

Read more about objects lifecycle events.

Use the off() function returned in the on() response to remove a lifecycle event listener:

JavaScript v2.9
// Initial subscription const { off } = map.on(('deleted') => console.log('Map deleted')); // To remove the listener off();
Copied!

Use the LiveMap.off() method to deregister a provided lifecycle event listener:

JavaScript v2.9
// Initial subscription const listener = () => console.log('Map deleted'); map.on('deleted', listener); // To remove the listener map.off('deleted', listener);
Copied!

Use the LiveMap.offAll() method to deregister all lifecycle event listeners:

JavaScript v2.9
map.offAll();
Copied!

A LiveMap can store other LiveMap or LiveCounter objects as values for its keys, enabling you to build complex, hierarchical object structure. This enables you to represent complex data models in your applications while ensuring realtime synchronization across clients.

JavaScript v2.9
// Create a hierarchy of objects using LiveMap const counter = await channel.objects.createCounter(); const map = await channel.objects.createMap({ nestedCounter: counter }); const outerMap = await channel.objects.createMap({ nestedMap: map }); await root.set('outerMap', outerMap); // resulting structure: // root (LiveMap) // └── outerMap (LiveMap) // └── nestedMap (LiveMap) // └── nestedCounter (LiveCounter)
Copied!
Select...