# Redux

[View on Github](https://github.com/CartoDB/carto-react-template)

{% hint style="warning" %}
**Note:** We are reducing our investment in CARTO for React and currently we discourage users from starting new projects with it.

CARTO for React is an opinionated framework with pre-built components and templates. This greatly speeds up the process to create React-based applications, but customization options are limited.

If you need further customization in React, or you want to build geospatial applications using **Vue, Angular, or any other Javascript-based framework**, we recommend going directly to the main CARTO for Developers documentation, including [CARTO + deck.gl](https://github.com/CartoDB/gitbook-documentation/blob/master/carto-for-developers/key-concepts/carto-for-deck.gl), which allows for maximum flexibility and scalability.
{% endhint %}

| Package            | Version                                                                                                                           | Downloads                                                                                                                            |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| @carto/react-redux | [![version](https://img.shields.io/npm/v/@carto/react-redux.svg?style=flat-square)](https://npmjs.org/package/@carto/react-redux) | [![downloads](https://img.shields.io/npm/dt/@carto/react-redux.svg?style=flat-square)](https://npmjs.org/package/@carto/react-redux) |

Functions to manage application state using React-Redux and the Redux Toolkit. This package includes 2 slices to manage the main redux blocks of a CARTO for React application. A [slice](#oauth-slice) is a way to manage a “portion” or *slice* of the redux store with a module:

* `cartoSlice`: to deal with basemap, viewState, sources, layers, and filters on sources.
* `oauthSlice`: to use an OAuth app.

**Tip:** The CARTO for React template already makes extensive use of these slices for redux out of the box, to provide several features in an easy way.

## CARTO Slice <a href="#carto-slice" id="carto-slice"></a>

### **createCartoSlice**

A function that accepts an `initialState`, setups the state, and creates the reducers that support CARTO for React architecture. In the CARTO 3 templates this slice includes also the OAuth settings; in the CARTO 2 templates there is a separate [slice](https://docs.carto.com/react/library-reference/redux/#oauth-slice) for OAuth settings.

* **Input**:

| Param        | Type     | Description       |
| ------------ | -------- | ----------------- |
| initialState | `Object` | the initial state |

An initial state object might look like:

```jsx
import { POSITRON } from "@carto/react-basemaps";

export const initialState = {
  viewState: {
    latitude: 31.802892,
    longitude: -103.007813,
    zoom: 2,
    pitch: 0,
    bearing: 0,
    dragRotate: false,
  },
  basemap: POSITRON,
  credentials: {
    username: "public",
    apiKey: "default_public",
    serverUrlTemplate: "https://{user}.carto.com",
  },
  googleApiKey: "",
};
```

### **addSource**

Action to add a **source** to the store.

* **Input**:

| Param                        | Type                               | Description                                                                                                                                                                                                             |
| ---------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| props                        | `Object`                           | { id, data, type, credentials, connection }                                                                                                                                                                             |
| props.id                     | `string`                           | Unique id for the source                                                                                                                                                                                                |
| props.data                   | `string`                           | Table name, tileset name or SQL query                                                                                                                                                                                   |
| props.type                   | `string`                           | Source type. Check available types [here](https://docs.carto.com/deck-gl/reference#type-string)                                                                                                                         |
| props.credentials            | `string`                           | Credentials for accessing the source                                                                                                                                                                                    |
| props.connection             | `string`                           | Connection name. Used only for CARTO 3.                                                                                                                                                                                 |
| props.filtersLogicalOperator | `FiltersLogicalOperators`          | Logical operation to use for combining filters. Can take the values `FiltersLogicalOperators.AND` and `FiltersLogicalOperators.OR`. Default value is `AND`. *Note: this property is only available beginning with v1.3* |
| \[props.queryParameters]     | `QueryParameters (@deck.gl/carto)` | Optional. SQL query parameters                                                                                                                                                                                          |

* **Example**:

```jsx
import { addSource } from "@carto/react-redux";
import { MAP_TYPES } from '@deck.gl/carto';

const source = {
  id: "sourceOne",
  type: MAP_TYPES.QUERY,
  connection: 'bqconn',
  data: "SELECT * FROM my_table",
  filtersLogicalOperator: FiltersLogicalOperators.OR
};

const action = addSource(source);
// dispatch(action);
```

### **removeSource**

Action to remove a source from the store

* **Input**:

| Param    | Type     | Description                |
| -------- | -------- | -------------------------- |
| sourceId | `string` | id of the source to remove |

* **Example**:

```jsx
import { removeSource } from "@carto/react-redux";

const action = removeSource("sourceOne");
// dispatch(action);
```

### **addLayer**

Action to add a Layer to the store. By default, the layer `visible` attribute is set to `true` unless the `layerAttributes` property overrides the `visible` property.

Important! This doesn’t imply adding a whole deck.gl layer to the redux store, just a “pointer” to it, by using an `id` shared with a Layer file + linking it to a `source`. See code generated by hygen assistants in the create-react-app template projects.

* **Input**:

| Param                    | Type     | Description                                       |
| ------------------------ | -------- | ------------------------------------------------- |
| props                    | `Object` | { id, source, layerAttributes }                   |
| props.id                 | `string` | unique id for the layer                           |
| props.source             | `string` | id of the source of the layer                     |
| \[props.layerAttributes] | `Object` | (optional) custom attributes to pass to the layer |

* **Example**:

```jsx
const action = addLayer({
  id: "layerOne",
  source: "sourceOne",
  layerAttributes: {
    extraAttribute: 1,
  },
});
// dispatch(action);
// extraAttribute will be available inside the Layer, for custom operations inside it (eg. styling)
```

### **updateLayer**

Action to update a Layer in the store

* **Input**:

| Param                 | Type     | Description                                        |
| --------------------- | -------- | -------------------------------------------------- |
| props                 | `Object` | { id, layerAttributes }                            |
| props.id              | `string` | unique id for the CARTO layer already in the store |
| props.layerAttributes | `Object` | custom attributes to update in the layer           |

* **Example**:

```jsx
const action = updateLayer({
  id: "layerOne",
  layerAttributes: {
    extraAttribute: 100,
  },
});
// dispatch(action);
// extraAttribute will be updated to the new value
```

### **removeLayer**

Action to remove a layer from the store

* **Input**:

| Param | Type     | Description               |
| ----- | -------- | ------------------------- |
| id    | `string` | id of the layer to remove |

* **Example**:

```jsx
const action = removeLayer("layerOne");
// dispatch(action);
```

### **setCredentials**

Action to set the default credentials parameters to use for requests to the CARTO platform.

* **Input**:

| Param       | Type     | Description                                                                                                                                         |
| ----------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| credentials | `Object` | CARTO platform credentials. Check the parameters [here](https://docs.carto.com/development-tools/carto-for-deck.gl/reference#setdefaultcredentials) |

* **Example**:

```jsx
import { API_VERSIONS } from "@deck.gl/carto";
import { setCredentials } from "@carto/react-redux";

      
const action = setCredentials({ 
  apiBaseUrl: 'https://gcp-us-east1.api.carto.com',
  apiVersion: API_VERSIONS.V3,
  accessToken: 'eyJhb...'
});
// dispatch(action);
```

### **setBasemap**

Action to set a basemap. To see available maps, check the reference for `@carto/react-basemaps`. If you use a Google Maps basemap, you would need to manage its api\_key properly.

* **Input**:

| Param   | Type     | Description            |
| ------- | -------- | ---------------------- |
| basemap | `String` | the new basemap to add |

* **Example**:

```jsx
import { DARK_MATTER } from "@carto/react-basemaps";
import { setBasemap } from "@carto/react-redux";

const action = setBasemap(DARK_MATTER);
// dispatch(action);
```

### **addFilter**

Action to add a filter on a given `source` by a `column`. This is done internally (and in a transparent way) by widgets.

* **Input**:

| Param           | Type         | Description                                                                 |
| --------------- | ------------ | --------------------------------------------------------------------------- |
| props           | `Object`     | { id, column, type, values, \[owner], \[params]}                            |
| props.id        | `string`     | Identifier of the source to apply the filter on                             |
| props.column    | `string`     | Column from the source to use by the filter                                 |
| props.type      | `FilterType` | Type of filter                                                              |
| props.values    | `array`      | Values for the filter (eg: \[‘a’, ‘b’] for ‘in’ or \[10, 20] for ‘between’) |
| \[props.owner]  | `string`     | (optional) Identifier of the widget triggering the filter (to be excluded)  |
| \[props.params] | `object`     | (optional) Additional filter parameters (depending on filter type)          |

* **Example**:

  This would apply a filter equivalent to a ‘WHERE country IN (‘Spain’)’ to the source. It is important to notice that a source can have multiple filters at the same type.

```jsx
import { addFilter } from "@carto/react-redux";

const action = addFilter({
  id: "sourceOne", // a valid sourceId
  column: "country",
  type: "in",
  values: ["Spain"],
});

// dispatch(action)
```

### **removeFilter**

Action to remove a column filter from a source.

* **Input**:

| Param        | Type     | Description                                      |
| ------------ | -------- | ------------------------------------------------ |
| props        | `Object` | { id, column }                                   |
| props.id     | `string` | sourceId of the source to remove the filter from |
| props.column | `string` | column of the filter to remove                   |

* **Example**:

  This would remove a filter (the previous example on addFilter)

```jsx
import { removeFilter } from "@carto/react-redux";

const action = removeFilter({
  id: "sourceOne",
  column: "country",
});

// dispatch(action)
```

### **clearFilters**

Action to remove all filters from a source.

* **Input**:

| Type | Description                                       |
| ---- | ------------------------------------------------- |
| `id` | sourceId of the source to remove all filters from |

* **Example**:

  This would remove all filters from a source with id ‘sourceOne’

```jsx
import { clearFilters } from "@carto/react-redux";

const action = clearFilters("sourceOne");

// dispatch(action)
```

### **selectSourceById**

Redux selector to get a source by ID

* **Input**:

| Param    | Type     | Description                            |
| -------- | -------- | -------------------------------------- |
| state    | `Object` | root redux state                       |
| sourceId | `string` | id of the source to recover from redux |

* **Example**:

```jsx
import { useSelector } from "react-redux";
import { selectSourceById } from "@carto/react-redux";

const source = useSelector((state) => selectSourceById(state, "sourceOne") || {});

// source is now available, for further operations
```

### **setViewState**

Action to set the current ViewState of the map.

* **Input**:

| Param     | Type     | Description                      |
| --------- | -------- | -------------------------------- |
| viewState | `Object` | ViewState, as defined by deck.gl |

* **Example** Example to increase the zoom level

```jsx
import { useSelector } from "react-redux";
import { setViewState } from "@carto/react-redux";

const zoomLevel = useSelector((state) => state.carto.viewState.zoom);
const action = setViewState({ zoom: zoomLevel + 1 });

// dispatch(action)
```

### **setWidgetLoadingState**

Action to set the loading state to a specific widget. It can be useful when creating custom widgets.

* **Input**:

| Param           | Type      | Description            |
| --------------- | --------- | ---------------------- |
| props           | `Object`  | { widgetId, isLoading} |
| props.widgetId  | `string`  | id of the widget       |
| props.isLoading | `boolean` | loading state          |

### **removeWidgetLoadingState**

Action to remove a specific widget loading state

* **Input**:

| Param    | Type     | Description      |
| -------- | -------- | ---------------- |
| widgetId | `string` | id of the widget |

### **setAllWidgetsLoadingStates**

Action to set the all the widgets loading state at once

* **Input**:

| Param      | Type      | Description   |
| ---------- | --------- | ------------- |
| areLoading | `boolean` | loading state |

## OAuth Slice <a href="#oauth-slice" id="oauth-slice"></a>

### **createOauthCartoSlice**

A function that accepts an initialState, setup the state, and creates reducers to manage OAuth with the CARTO 2 platform. This slice is not used with CARTO 3 templates because OAuth is managed through the Auth0 React SDK.

* **Input**:

| Param        | Type     | Description       |
| ------------ | -------- | ----------------- |
| initialState | `Object` | the initial state |

An initial state object might look like:

```jsx
  export const oauthInitialState = {
    oauthApp: {
      clientId: 'YOUR-CARTO-OAUTH-APP-CLIENTID'
      scopes: [
        'user:profile', // to load avatar photo
        'datasets:metadata', // to list all your datasets,
        'dataservices:geocoding', // to use geocoding through Data Services API
        'dataservices:isolines', // to launch isochrones or isodistances through Data Services API
      ],
      authorizeEndPoint: 'https://carto.com/oauth2/authorize',
    }
  };
```

### **setTokenAndUserInfoAsync**

Action to set the userInfo in the redux store, once there is a valid token (and set them both in state).

* **Input**:

| Param | Type     | Description                                                                                    |
| ----- | -------- | ---------------------------------------------------------------------------------------------- |
| props | `Object` | oauthParams, as returned by `useOAuthLogin` hook ({ accessToken, expirationDate, userInfoUrl}) |

* **Example**:

```jsx
import { setTokenAndUserInfoAsync } from "@carto/react-redux";

// const oauthApp = { whatever your app requires... }

const onParamsRefreshed = (oauthParams) => {
  if (oauthParams.error) {
    console.error(`OAuth error: ${oauthParams.error}`);
  } else {
    const action = setTokenAndUserInfoAsync(oauthParams);
    dispatch(action);
  }
};

const [handleLogin] = useOAuthLogin(oauthApp, onParamsRefreshed);

/* 
    oauthParams look something like:
    { 
      accessToken: "xxxxxxxxx", 
      expirationDate: 1616013732973.8652, 
      userInfoUrl: "https://a-certain-user.carto.com/api/v4/me"
    }
  */
```

### **logout**

Action to logout, removing user info & token from redux store.

* **Example**:

```jsx
import { logout } from "@carto/react-redux";

const action = logout();
// dispatch(action)
```

### **selectOAuthCredentials**

Selector to fetch the current OAuth credentials from the redux store.

* **Returns**:

| Param                         | Type     | Description                             |
| ----------------------------- | -------- | --------------------------------------- |
| credentials                   | `Object` | { username, apiKey, serverUrlTemplate } |
| credentials.username          | `string` | CARTO username                          |
| credentials.apiKey            | `string` | apiKey coming from OAuth                |
| credentials.serverUrlTemplate | `string` | required for further api requests       |

* **Example**:

```jsx
import { useSelector } from "react-redux";
import { selectOAuthCredentials } from "@carto/react-redux";

const oauthCredentials = useSelector(selectOAuthCredentials);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.carto.com/carto-for-developers/carto-for-react/library-reference/redux.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
