https://github.com/brigonzalez/redux-modular-fetch-middleware
A modular redux middleware for using fetch
https://github.com/brigonzalez/redux-modular-fetch-middleware
action creator dispatch fetch middleware modular redux
Last synced: 26 days ago
JSON representation
A modular redux middleware for using fetch
- Host: GitHub
- URL: https://github.com/brigonzalez/redux-modular-fetch-middleware
- Owner: brigonzalez
- Created: 2018-05-11T01:45:00.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-05-13T20:44:26.000Z (about 8 years ago)
- Last Synced: 2025-10-02T02:58:03.455Z (8 months ago)
- Topics: action, creator, dispatch, fetch, middleware, modular, redux
- Language: JavaScript
- Homepage:
- Size: 277 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# redux-modular-fetch-middleware
> A modular redux middleware for using fetch
---
## Table of Contents
1. [Getting Started](#getting-started)
2. [Documentation](#documentation)
3. [Best Practices](#best-practices)
---
### Getting Started
- Download `redux-modular-fetch-middleware` using `npm i redux-modular-fetch-middleware` or `yarn add redux-modular-fetch-middleware`
- Apply the middleware using the `redux-modular-fetch-middleware` default export, like so...
```javascript
import { createStore, applyMiddleware } from 'redux'
import fetchMiddleware from 'redux-modular-fetch-middleware';
...
applyMiddleware(fetchMiddleware);
```
- Define a `fetch` object with a `url` property on the dispatch you want to call fetch
```javascript
const actionCreatorMethod = () => ({
fetch: {
url: 'https://someurl.com'
},
type: SOME_ACTION_TYPE
});
```
That's it! A `fetch` object with a `url` property is all you need to call fetch on an action.
- `fetch` The required object on a dispatch call to call fetch
- `url` The url that will be called by fetch
You can define what the request `method`, `body`, and `header` look like. In fact, any options that you can define in fetch natively will be passed on just as if you were calling fetch yourself.
- `options` Fetch options with properties like `method`, `header`, and `body`. By default, `GET` will be used as the request method
```javascript
const setUserActionCreator = () => ({
fetch: {
options: {
body: {
user: {
name: 'First Last',
address: '123 Main St.'
}
},
method: 'POST'
},
url: 'https://someapi.com/user'
},
type: SET_USER_REQUEST
});
```
If you're retrieving data, you can define what response method will be used to retrieve that data.
- `responseMethod` The [response method](https://developer.mozilla.org/en-US/docs/Web/API/Body) used to retrieve data. By default, `json` will be used as the response method if the `header` content-type is 'application/json'. **Warning:** If a `responseMethod` is provided and your fetch call returns a response that is not resolvable by the `responseMethod` provided, the Promise will be rejected.
```javascript
const getProfilePicActionCreator = (userId) => ({
fetch: {
responseMethod: 'blob',
url: `https://someapi.com/user/${userId}/profilePic`
},
type: GET_PROFILE_PIC_REQUEST
});
```
Being able to call fetch without being able to access the data or error isn't very useful. Those options are provided through the properties shown below.
- `onFailure` The function that will be called if the fetch request fails. Called with `dispatch`, `getState`, and `error`
- `onSuccess` The function that will be called if the fetch request succeeds. Called with `dispatch`, `getState`, and `data`
You are also given the `store`'s current `getState` and `dispatch` function to notify your reducers your request was successful or unsuccessful.
```javascript
const getProfilePicActionCreator = (userId) => ({
fetch: {
onFailure: (dispatch, getState, error) => {
dispatch({
error: error,
type: GET_PROFILE_PIC_FAILURE
});
},
onSuccess: (dispatch, getState, data) => {
dispatch({
data: data,
type: GET_PROFILE_PIC_SUCCESS
});
},
responseMethod: 'blob',
url: `https://someapi.com/user/${userId}/profilePic`
},
type: GET_PROFILE_PIC_REQUEST
});
```
You can even define what fetch implementation you would like the middleware to use when applying the middleware.
```javascript
import crossFetch from 'cross-fetch';
import fetchMiddleware from 'redux-modular-fetch-middleware';
...
applyMiddleware(fetchMiddleware(crossFetch));
```
This can be especially useful when wanting to set global options in your fetch request like `header` and `credentials`. By default, `window.fetch` will be used as the fetch implementation.
---
### Documentation
**Required Object**
- `fetch` The required object on a dispatch call to call fetch
**Required Properties on `fetch` Object**
- `url` The url that will be called by fetch
**Optional Properties on `fetch` Object**
- `onFailure` The function that will be called if the fetch request fails. Called with `dispatch`, `getState`, and `error`
- `onSuccess` The function that will be called if the fetch request succeeds. Called with `dispatch`, `getState`, and `data`
- `options` Fetch options with properties like `method`, `header`, and `body`. By default, `GET` will be used as the request method
- `responseMethod` The [response method](https://developer.mozilla.org/en-US/docs/Web/API/Body) used to retrieve data. By default, `json` will be used as the response method if the `header` content-type is 'application/json'. **Warning:** If a `responseMethod` is provided and your fetch call returns a response that is not resolvable by the `responseMethod` provided, the Promise will be rejected.
- 'arrayBuffer'
- 'blob'
- 'formData'
- 'json'
- 'text'
**Fetch Implementation**
The fetch implementation can be defined by passing it in as the parameter when applying the middleware. By default, `window.fetch` will be used as the fetch implementation.
---
### Best Practices
**Async Actions**
[Redux docs](https://redux.js.org/advanced/async-actions#actions) suggest using three actions for an asynchronous request: an action indicating your request began, an action indicating your request succeeded, and an action indicating your request failed. Below is an example of how to heed this suggestion using `redux-modular-fetch-middleware`.
```javascript
const getUserActionCreator = (userId) => ({
fetch: {
onFailure: (dispatch, getState, error) => {
dispatch({
error: error,
type: GET_USER_FAILURE
});
},
onSuccess: (dispatch, getState, data) => {
dispatch({
data: data,
type: GET_USER_SUCCESS
});
},
url: `https://someapi.com/user/${userId}`
},
type: GET_USER_REQUEST
});
```