|
| 1 | +redux-actions |
| 2 | +============= |
| 3 | + |
| 4 | +API Add on for [Flux Standard Action](https://github.com/acdlite/flux-standard-action) utilities for Redux. |
| 5 | + |
| 6 | +```js |
| 7 | +npm install --save redux-actions |
| 8 | +``` |
| 9 | +```js |
| 10 | +import { createAPIAction } from 'redux-actions-api-addon'; |
| 11 | +``` |
| 12 | + |
| 13 | +### The Problem? |
| 14 | + |
| 15 | +When creating redux actions for API Requests, in reality there are 3 actions that are spawned |
| 16 | + |
| 17 | +1. Request Event |
| 18 | +2. Success Event |
| 19 | +3. Failure Event |
| 20 | + |
| 21 | +This can lead to a _lot_ of boilerplate. |
| 22 | + |
| 23 | +Now, there are some packages out there to handle this ex: [https://github.com/agraboso/redux-api-middleware](https://github.com/agraboso/redux-api-middleware) However, these packages aren't FSA Compliant [https://github.com/acdlite/flux-standard-action](https://github.com/acdlite/flux-standard-action) |
| 24 | + |
| 25 | +This add on attemps to solve 2 things: |
| 26 | + |
| 27 | +1. Reduce boilerplate by auto dispatching Request, Success, and Failure Events |
| 28 | +2. Be FSA Compliant |
| 29 | + |
| 30 | +In order to be FSA Compliant, most of the information is stored in the `meta` object. |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | +### `createAPIAction(type, method, endpoint, payloadCreator = Identity, ?metaCreator)` |
| 35 | + |
| 36 | +Wraps an action creator so that its return value is the payload of a Flux Standard Action, and also creates multiple actions types that can be handled via middleware (Request, Success, and Failure Types). |
| 37 | + |
| 38 | +The parameters you pass to your action are **verb dependant** |
| 39 | + |
| 40 | +Also adds `meta` data, such as the `method` and `endpoint` to be used where you see fit. |
| 41 | + |
| 42 | +If no payload creator is passed, or if it's not a function, the identity function is used. |
| 43 | + |
| 44 | + |
| 45 | +Example: |
| 46 | + |
| 47 | +```js |
| 48 | +let createContact = createAPIAction('CREATE_CONTACT', 'POST', '/contacts' ); |
| 49 | + |
| 50 | +expect(createContact( {name: "James Kusachi"} )).to.deep.equal({ |
| 51 | + type: 'CREATE_CONTACT', |
| 52 | + payload: {name: "James Kusachi"}, |
| 53 | + meta: { |
| 54 | + api: true, |
| 55 | + method: 'POST', |
| 56 | + endpoint: '/contacts', |
| 57 | + types: [ |
| 58 | + 'CREATE_CONTACT_REQUEST', |
| 59 | + 'CREATE_CONTACT_SUCCESS', |
| 60 | + 'CREATE_CONTACT_FAILURE', |
| 61 | + ] |
| 62 | + } |
| 63 | +}); |
| 64 | +``` |
| 65 | + |
| 66 | +If the payload is an instance of an [Error |
| 67 | +object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error), |
| 68 | +redux-actions will automatically set ```action.error``` to true. |
| 69 | + |
| 70 | +The following are **Verb Based Examples** so you can see how to use your actions |
| 71 | + |
| 72 | +##### GET |
| 73 | +```js |
| 74 | +let getItems = createAPIAction('ITEMS', 'GET', '/items' ); |
| 75 | +getItems() |
| 76 | + |
| 77 | +``` |
| 78 | +there is no need to pass a payload to your action, as its a `GET` request |
| 79 | + |
| 80 | +*Auto Generated Action Types* |
| 81 | +- `ITEMS_GET_REQUEST` |
| 82 | +- `ITEMS_GET_SUCCESS` |
| 83 | +- `ITEMS_GET_FAILURE` |
| 84 | + |
| 85 | +##### GET (single) |
| 86 | +```js |
| 87 | +let getSingleItem = createAPIAction('SINGLE_ITEM', 'GET', '/items' ); |
| 88 | +getSingleItem(15) |
| 89 | + |
| 90 | +``` |
| 91 | +Here, we pass `15` as a parameter to the action, representing a case where we want only 1 item. |
| 92 | +It's also important to note that we used a separate key, `SINGLE_ITEM`, to differentiate between |
| 93 | +a single and All request. |
| 94 | + |
| 95 | +*Auto Generated Action Types* |
| 96 | +- `SINGLE_ITEM_GET_REQUEST` |
| 97 | +- `SINGLE_ITEM_GET_SUCCESS` |
| 98 | +- `SINGLE_ITEM_GET_FAILURE` |
| 99 | + |
| 100 | +##### POST |
| 101 | + |
| 102 | +```js |
| 103 | +let createItem = createAPIAction('ITEMS', 'POST', '/items' ); |
| 104 | +createItem({name: "James Kusachi"}); |
| 105 | +``` |
| 106 | +In a case where you `POST` new data, you dont need to specify an id, but you do need to pass data. |
| 107 | +Any data passed as the first parameter will be treated as the payload to be sent across. |
| 108 | + |
| 109 | +*Auto Generated Action Types* |
| 110 | +- `ITEMS_POST_REQUEST` |
| 111 | +- `ITEMS_POST_SUCCESS` |
| 112 | +- `ITEMS_POST_FAILURE` |
| 113 | + |
| 114 | +##### PUT |
| 115 | + |
| 116 | +```js |
| 117 | +let updateItem = createAPIAction('ITEMS', 'PUT', '/items' ); |
| 118 | +updateItem(15, {name: "Ronald McDonald"}); |
| 119 | + |
| 120 | +``` |
| 121 | +In the event of an `UPDATE`, you generally need to specify 2 pieces |
| 122 | +* id of item you are updating |
| 123 | +* the data you want to update with |
| 124 | + |
| 125 | +In this case, we are updating primary item `15` with a new object |
| 126 | + |
| 127 | +*Auto Generated Action Types* |
| 128 | +- `ITEMS_PUT_REQUEST` |
| 129 | +- `ITEMS_PUT_SUCCESS` |
| 130 | +- `ITEMS_PUT_FAILURE` |
| 131 | + |
| 132 | +##### DELETE |
| 133 | +```js |
| 134 | +let deleteItem = createAPIAction('ITEMS', 'DELETE', '/items' ); |
| 135 | +updateItem(15); |
| 136 | + |
| 137 | +``` |
| 138 | +In the case of `DELETE`, you just need to specify the primary id of tha which you want to delete. |
| 139 | +No need to pass in any payload data, as that would get dropped anyways because of `DELETE` |
| 140 | + |
| 141 | +*Auto Generated Action Types* |
| 142 | +- `ITEMS_DELETE_REQUEST` |
| 143 | +- `ITEMS_DELETE_SUCCESS` |
| 144 | +- `ITEMS_DELETE_FAILURE` |
| 145 | + |
0 commit comments