# Getting started: LiveObjects in JavaScript This guide shows how to integrate Ably LiveObjects into your JavaScript / TypeScript application. You will learn how to: * Create an Ably account and get an API key for authentication. * Install the Ably Pub/Sub SDK. * Create a channel with LiveObjects functionality enabled. * Use the [PathObject API](https://ably.com/docs/liveobjects/concepts/path-object.md) to access objects on a channel. * Create, update and subscribe to changes on LiveObjects data structures: [LiveMap](https://ably.com/docs/liveobjects/map.md) and [LiveCounter](https://ably.com/docs/liveobjects/counter.md). ## Authentication An [API key](https://ably.com/docs/auth.md#api-keys) is required to authenticate with Ably. API keys are used either to authenticate directly with Ably using [basic authentication](https://ably.com/docs/auth/basic.md), or to generate tokens for untrusted clients using [token authentication](https://ably.com/docs/auth/token.md). [Sign up](https://ably.com/sign-up) for a free account and create your own API key in the [dashboard](https://ably.com/dashboard) or use the [Control API](https://ably.com/docs/platform/account/control-api.md) to create an API key programmatically. API keys and tokens have a set of [capabilities](https://ably.com/docs/auth/capabilities.md) assigned to them that specify which operations can be performed on which resources. The following capabilities are available for LiveObjects: * `object-subscribe` - grants clients read access to LiveObjects, allowing them to get the channel object and subscribe to updates. * `object-publish` - grants clients write access to LiveObjects, allowing them to perform mutation operations on objects. To use LiveObjects, an API key must have at least the `object-subscribe` capability. With only this capability, clients will have read-only access, preventing them from calling mutation methods on LiveObjects. For the purposes of this guide, make sure your API key includes both `object-subscribe` and `object-publish` [capabilities](https://ably.com/docs/auth/capabilities.md) to allow full read and write access. ## Install Ably Pub/Sub SDK LiveObjects is available as part of the Ably Pub/Sub SDK via the dedicated Objects plugin. ### NPM Install the Ably Pub/Sub SDK as an [NPM module](https://www.npmjs.com/package/ably): ```shell npm install ably ``` Import the SDK and the Objects plugin into your project: ```javascript import * as Ably from 'ably'; import { LiveObjects, LiveMap, LiveCounter } from 'ably/liveobjects'; ``` ### CDN Reference the Ably Pub/Sub SDK and the Objects plugin within your HTML file: ```javascript ``` ## Instantiate a client Instantiate an Ably Realtime client from the Pub/Sub SDK, providing the Objects plugin: ```javascript const realtimeClient = new Ably.Realtime({ key: 'your-api-key', plugins: { LiveObjects } }); ``` A [`ClientOptions`](https://ably.com/docs/api/realtime-sdk.md#client-options) object may be passed to the Pub/Sub SDK instance to further customize the connection, however at a minimum you must set an API key and provide an `Objects` plugin so that the client can use LiveObjects functionality. ## Create a channel LiveObjects is managed and persisted on [channels](https://ably.com/docs/channels.md). To use LiveObjects, you must first create a channel with the correct [channel mode flags](https://ably.com/docs/channels/options.md#modes): * `OBJECT_SUBSCRIBE` - required to access objects on a channel. * `OBJECT_PUBLISH` - required to create and modify objects on a channel. ```javascript const channelOptions = { modes: ['OBJECT_SUBSCRIBE', 'OBJECT_PUBLISH'] }; const channel = realtimeClient.channels.get('my_liveobjects_channel', channelOptions); ``` ## Get the channel object The [`channel.object`](https://ably.com/docs/api/realtime-sdk/channels.md#object) property gives access to the LiveObjects API for a channel. Use `channel.object.get()` to obtain a [`PathObject`](https://ably.com/docs/liveobjects/concepts/path-object.md) that represents the channel object. The channel object is a [`LiveMap`](https://ably.com/docs/liveobjects/map.md) that always exists on a channel and acts as the top-level entry point for accessing and persisting objects. A `PathObject` provides a path-based API for accessing and manipulating the object hierarchy. The method returns a promise that resolves once the LiveObjects state is synchronized with the Ably system: ```javascript // Returns a PathObject to the channel object // The promise resolves once synchronized with Ably const myObject = await channel.object.get(); ``` ## Create and assign objects You can create and assign objects using the `LiveMap.create()` and `LiveCounter.create()` static methods. These methods create value types that can be assigned to paths in the object hierarchy: ```javascript // Create and assign a counter in one operation await myObject.set('visits', LiveCounter.create(0)); // Create and assign a map with initial data await myObject.set('reactions', LiveMap.create({ likes: 0, hearts: 0 })); const visitsCounter = myObject.get('visits'); const reactionsMap = myObject.get('reactions'); ``` ## Subscribe to updates Subscribe to realtime updates using the `subscribe()` method on a `PathObject`. You will be notified when the object at that path is updated by other clients or by you: ```javascript // Subscribe to counter updates visitsCounter.subscribe(({ object }) => { console.log('Visits counter updated:', object.value()); }); // Subscribe to map updates reactionsMap.subscribe(({ object }) => { console.log('Reactions map updated:', [...reactionsMap.entries()]); }); ``` The subscription callback receives an event object with: - `object`: A `PathObject` representing the path at which there was an object change - `message`: The `ObjectMessage` that carried the operation that led to the change ## Update objects Update objects using mutation methods on `PathObject`. All subscribers (including you) will be notified of the changes: ```javascript // Update counter await visitsCounter.increment(5); // console: "Visits counter updated: 5" await visitsCounter.decrement(2); // console: "Visits counter updated: 3" // Update map await reactionsMap.set('likes', 10); // console: "Reactions map updated: [['likes',10]]" await reactionsMap.set('hearts', 5); // console: "Reactions map updated: [['likes',10],['hearts',5]]" await reactionsMap.remove('likes'); // console: "Reactions map updated: [['hearts',5]]" ``` ## Next steps This quickstart introduced the basic concepts of LiveObjects and demonstrated how the path-based API works. The next steps are to: * Learn about the [PathObject](https://ably.com/docs/liveobjects/concepts/path-object.md) and [Instance](https://ably.com/docs/liveobjects/concepts/instance.md) APIs. * Read more about [LiveCounter](https://ably.com/docs/liveobjects/counter.md) and [LiveMap](https://ably.com/docs/liveobjects/map.md). * Learn about [Batching Operations](https://ably.com/docs/liveobjects/batch.md). * Learn about [Objects Lifecycle Events](https://ably.com/docs/liveobjects/lifecycle.md). * Add [Typings](https://ably.com/docs/liveobjects/typing.md) for your LiveObjects.