---
title: Guide - Mapping
sidebar_label: Mapping
---

# Response Mapping

You can set the mapping of data returned from the request. This data will not be modified in the cache; it will only be modified within the given request.
This means that the mapping will be included locally and not globally in the cache.

By making two requests to the same place with two different mappers, we can still use everything the library offers - deduplication, cache, etc.
The mapper does not affect other requests, only the one to which it is attached.
Thanks to this, we do not have to change the cache keys for each mapped request.

:::info

Mappers can be asynchronus. This way we can build up bigger responses.

:::

#### Example

```ts
export const getUser = client
  .createRequest<UserModel>()({
    method: "GET",
    endpoint: "/users/:userId",
  })
  .setResponseMapper(async (response) => {
    if (response.data) {
      const products = await getProducts.send();
      return {
        ...response,
        data: {
          ...response.data,
          products, // Add custom data to response
          createdAt: new Date(response.data.createdAt), // Always transforms ISO string to Date!
        },
      };
    }
    return response;
  });
```

## Model Hydration

We can hydrate class models, which can parse our data.
For example, the User class can parse dates from an ISO string into a Date object, generate nicknames or full names, etc.

```ts
export const getUser = client
  .createRequest<UserModel>()({
    method: "GET",
    endpoint: "/users/:userId",
  })
  .setResponseMapper((response) => {
    if (response.data) {
      return new User(response.data);
    }
    return response;
  });
```

---

# Request Mapping

You can map requests - i.e. make changes to a request before executing it. This allows us to validate the sent data and change its format or state.

:::info

Mappers can be asynchronous. This lets us build up bigger responses.

:::

#### Example

```ts
export const postUser = client
  .createRequest<UserModel, UserData>()({
    method: "POST",
    endpoint: "/users/:userId",
  })
  .setRequestMapper((request) => {
    const formData = new FormData();

    Object.entries(request.data).forEach(([key, value]) => {
      formData.append(key, value);
    });

    // Add custom headers and map data for every request
    return request.setHeaders({ ...request.headers, "X-Better-Typed": "My custom header" }).setData(formData);
  });
```
