---
sidebar_position: 4
title: Socket Listener
sidebar_label: Listener
---

<div class="api-link">
  <div class="api-link-title">Listener</div>
  <div class="api-link-sub-title">

[Read the API Reference »](/api/Sockets/Class/Listener.mdx)

  </div>
</div>

---

## Introduction

**`Listener`** is a class that creates a template for receiving events from server. Its strength is its strict and
predictable data structure which together with typescript gives a lot of confidence while developing data exchange
features.

To use the listener we need to trigger the `listen` method with provided callback.

---

## Purpose

- Configures events listeners templates
- Standardizes the system’s data schema
- Listen to server events

---

## Initialization

Listener should be initialized from the Socket instance with `createListener` method. This passes a shared reference to
the place that manages communication in the application.

```tsx
import { socket } from "./socket";

export const onChatMessage = socket.createListener<ChatMessageType>()({
  endpoint: "chat-message", // endpoint of the event
});

export const onUserStatusChange = socket.createListener<UserStatusType>()({
  endpoint: "status", // endpoint of the event
});
```

---

## Usage

### Listening

Use the `listen` method to start the listening for incoming events.

```tsx
onChatMessage.listen({
  callback: (message) => {
    // message have type ChatMessageType
    console.log(message);
  },
});
```

### Remove listener

Use the returned method to stop listening.

```tsx
const removeEvent = onChatMessage.listen({ callback: (message) => console.log(message) });

...

removeEvent() // We remove listener
```

Remove event listeners directly from the adapter

```tsx
const callback = (message) => console.log(message);
const removeEvent = onChatMessage.listen({ callback });

...

socket.adapter.listeners.delete(onChatMessage.endpoint) // We remove ALL listeners from given event
socket.adapter.listeners.get(onChatMessage.endpoint).delete(callback) // We remove single listener from given event
```

Listen to event `once`

```tsx
const removeEvent = onChatMessage.listen({
  callback: (message) => {
    console.log(message);
    removeEvent(); // We listen only to single event
  },
});
```

---

## Listening with onData hook

You can use `onData` method to listen to all events of given listener. This method is useful when you want to attach
some logic to any occurrence of the event. It's additional way of hooking into the listener groups.

```ts
export const onNoteChange = socket
  .createListener<NoteData>()({
    endpoint: "notes/:id",
  })
  .onData((event) => {
    // We will receive all events from given listener,
    // no mater of ID, as it will be filled later on while listening
    console.log(event);
  });

onNoteChange.setParams({ noteId: 1 }).listen(() => {
  // some logic
});

onNoteChange.setParams({ noteId: 2 }).listen(() => {
  // some logic
});

// console.log(event) ===> { noteId: 1, ... }
// console.log(event) ===> { noteId: 2, ... }
```

### Integration with Hyper Fetch

We can use this to make simple integration with Hyper Fetch. We can use `onData` hook to update the cache with new data
from the socket.

```ts

// ==> Our core setup
const client = new Client({ url: "http://localhost:3000" });
const getNote = client.createRequest()({
  endpoint: "/note/:noteId";
})


// ==> Our realtime listener

export const onNoteChange = socket.createListener<NoteData>()({
  endpoint: "notes",
}).onData((event) => {
  const { noteId } = event;

  // Fill the params so our cache can find the request in storage
  const noteRequest = client.cache.get(getNote.setParams({ noteId }));

  // Update the cache
  client.cache.update(noteRequest, (prevData) => {
    return {...prevData, data: event}
  });
});

```

---

## Methods

Using methods on a listener is different from other classes in Hyper Fetch. This is to ensure isolation between
different uses, which allows you to avoid overwriting previously-prepared listeners and to dynamically generate keys for
queues or the cache.

:::danger

Using any method on listener returns its clone! `We don't return a reference!`

:::

```tsx
// ❌ WRONG

const listener = getChatMessageListener;

listener.setOptions({ ... }); // Returns CLONED listener with assigned options

listener.listen(); // Error - no options will be applied
```

```tsx
// ✅ Good

const listener = getChatMessageListener;

const listenerWithOptions = listener.setOptions({ ... }); // Returns CLONED listener with assigned options

listenerWithOptions.listen(); // Success - options applied
```

---

## Parameters

Configuration options

{@import Sockets ListenerOptionsType returns}
