redux-observable-requests
A lightweight minimalistic approach to AJAX requests using rxjs
and redux-observable
.
Table of Contents
Motivation
When working in multiple projects, boilerplate code can start to become an issue. Especially maintaining the boilerplate for AJAX requests among multiple projects. redux-observable-requests
was created to centralize AJAX requests in one place, eliminate manually writting multiple action types for success, error, and abort actions, and provide a method to intercept requests and responses before they are dispatched, all while creating as small of a footprint as possible.
redux-observable-requests
is designed to use as many internal rxjs
components as possible. For this reason redux-observable-requests
only uses the built in rxjs/ajax
class when handing AJAX requests. Future versions may allow for the implementation of other third party request libraries. If you require any specific features, please submit an issue so I can better prioritize requests.
Getting Started
Installation
npm install --save redux-observable-requests
Implementation
// Import the custom request subscriber generator. // Add the request subscriber to your root epic.;
Optionally, you can pass custom callback functions to the request subscriber generator to alter actions before they are dispatched, dispatch other actions, or run side effects.
// Import the custom request subscriber generator. const handleSuccessAction = { // Normalize responseAction.response, log console data, etc... return responseAction // Callback functions must return an action. This action is passed along to dispatch.} const handleAbortAction = { console; return responseAction} const handleRequestAction = { // Add authorization tokens, log activity, dispatch side effects, etc... return requestAction} // Add the request subscriber to your root epic.;
Making Requests
Simply add a request
property inside of a redux action. FSA complaint actions will be detected maintained depending on the location of the request
key.
The request
property values are directly passed to rxjs/ajax
and is a type of AjaxRequest
. The response
property within a responding action of a request action extends a type of AjaxResponse
.
const getUser = type: 'GET_USER' request: url: `https://someapi/users/` method: 'get'
Reading Responses
Responding actions will be either of error, success, or abort. Action types are appended to the original action type. To help streamline implementation helper functions have been provided.
Any properties in the original actions meta
property will be copied to the responding actions meta
property.
AjaxResponse.response
Is mapped to ResponseAction.response
and contains only the web servers response data, whereas the full AjaxResponse
can be found under ResponseAction.meta.ajaxResponse
. For more information on structure, refer to index.ts
which shows the type interfaces for response actions.
// Import the success helper function. const users = { }
Canceling Duplicate Actions
If a request action has been dispatched, any other actions with the same type will automatically be aborted until the original action is completed. Aborted requests will trigger an abort action to be dispatched. Aborted requests are not qued and are currently discarded. You can retreive an aborted request by watching for the abort action, and retreiving the original request from action.meta.originalAction.request
.
Typescript Support
Typescript is fully supported and redux-observable-requests
is written natively using Typescript.
const getUser: RequestAction = type: 'GET_USER' request: url: `https://someapi/users/` method: 'get'
const users = { } const userErrors = { } const abortedActions = { }
const handleSuccessAction = responseAction: ResponseAction: { // Normalize responseAction.response, log console data, etc... return responseAction} const handleAbortAction = responseAction: ResponseAction: { console; return responseAction} const handleRequestAction = requestAction: RequestAction: { // Add authorization tokens, log activity, dispatch side effects, etc... return requestAction} ;
Contributing
All contributions are welcome, however I would ask that any and all pull requests have a corresponding issue first, just so we can figure out any details prior to work being performed.