# Typing The `Typing` interface provides methods for sending and receiving typing indicators in a chat room. Access it via `room.typing`. #### Javascript ``` const typing = room.typing; ``` ## Properties The `Typing` interface has the following properties: | Property | Description | Type | | --- | --- | --- | | current | The current set of client IDs who are typing in the room. | `Set` |
## Start typing `typing.keystroke(): Promise` Sends a typing started event to notify other users that the current user is typing. Events are throttled according to the [`heartbeatThrottleMs`](https://ably.com/docs/chat/api/javascript/rooms.md#get) room option to prevent excessive network traffic. If called within the throttle interval, the operation becomes a no-op. Multiple rapid calls are serialized to maintain consistency. The room must be [attached](https://ably.com/docs/chat/api/javascript/room.md#attach) and the connection must be in the [`connected`](https://ably.com/docs/chat/api/javascript/connection.md) state. ### Javascript ``` // Call this when the user starts typing await room.typing.keystroke(); ``` ### Returns `Promise` Returns a promise. The promise is fulfilled when the typing event has been sent, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object. ## Stop typing `typing.stop(): Promise` Sends a typing stopped event to notify other users that the current user has stopped typing. If the user is not currently typing, this operation is a no-op. Multiple rapid calls are serialized to maintain consistency. The room must be [attached](https://ably.com/docs/chat/api/javascript/room.md#attach) and the connection must be in the [`connected`](https://ably.com/docs/chat/api/javascript/connection.md) state. ### Javascript ``` // Call this when the user stops typing or clears the input await room.typing.stop(); ``` ### Returns `Promise` Returns a promise. The promise is fulfilled when the stop event has been sent, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object. ## Subscribe to typing events `typing.subscribe(listener: TypingListener): Subscription` Subscribes to typing events from users in the chat room. Receives updates whenever a user starts or stops typing, providing real-time feedback about who is currently composing messages. The room must be [attached](https://ably.com/docs/chat/api/javascript/room.md#attach) to receive typing events. ### Javascript ``` const { unsubscribe } = room.typing.subscribe((event) => { console.log('Currently typing:', Array.from(event.currentlyTyping)); }); // To stop receiving typing events unsubscribe(); ``` ### Parameters The `subscribe()` method takes the following parameters: | Parameter | Required | Description | Type | | --- | --- | --- | --- | | listener | Required | Callback invoked when the typing state changes. |
|
| Property | Description | Type | | --- | --- | --- | | type | The type of the event. Always `SetChanged`. |
| | currentlyTyping | Set of client IDs currently typing in the room. | `Set` | | change | Information about the specific change that triggered this event. |
|
| Value | Description | | --- | --- | | SetChanged | The set of currently typing users has changed. The value is `typing.set.changed`. |
| Property | Description | Type | | --- | --- | --- | | clientId | The client ID whose typing state changed. | String | | type | Whether the user started or stopped typing. |
|
| Value | Description | | --- | --- | | Started | A user has started typing. The value is `typing.started`. | | Stopped | A user has stopped typing. The value is `typing.stopped`. |
### Returns `Subscription` Returns an object with the following methods: #### Unsubscribe from typing events `unsubscribe(): void` Call `unsubscribe()` to stop receiving typing events. ## Example ### Javascript ``` const room = await chatClient.rooms.get('my-room', { typing: { heartbeatThrottleMs: 5000 // Throttle typing events to every 5 seconds } }); await room.attach(); // Subscribe to typing events const { unsubscribe } = room.typing.subscribe((event) => { const typingUsers = Array.from(event.currentlyTyping); if (typingUsers.length === 0) { console.log('No one is typing'); } else if (typingUsers.length === 1) { console.log(`${typingUsers[0]} is typing...`); } else { console.log(`${typingUsers.join(', ')} are typing...`); } }); // Integrate with an input field const inputField = document.getElementById('message-input'); inputField.addEventListener('input', async () => { if (inputField.value.length > 0) { await room.typing.keystroke(); } else { await room.typing.stop(); } }); inputField.addEventListener('blur', async () => { await room.typing.stop(); }); // Check who is currently typing console.log('Currently typing:', room.typing.current); // Clean up unsubscribe(); ```