Simplifying request/success/failure model for async action in Redux for large applications
Tags: javascript, react, redux, productivity
Published: 2020-12-18 18:14:00

|Request/Success/Failure Pattern in Redux (2 Part series)|
|-----|
|[Part 1: Using request/success/failure pattern in Redux to handle async actions](https://dev.to/sunil12738/using-request-success-failure-pattern-in-redux-to-handle-async-actions-4d0)|
|[**Part 2: Simplifying request/success/failure model for async action in Redux for large applications**](https://dev.to/sunil12738/simplifying-request-success-failure-model-for-async-action-in-redux-for-large-applications-1n9g)|

Now that we have learnt the pattern to skillfully handle the async actions in redux, let's dive deeper into how to simplify the same to make code more cleaner and scalable. For those who missed the Part 1, [please read here](https://dev.to/sunil12738/using-request-success-failure-pattern-in-redux-to-handle-async-actions-4d0).

## Why to simplify?
Notice that, we have written a lot of boilerplate code just to handle one API call. Also, code will become repetitive in nature for multiple calls which contradicts with DRY and other software writing methodologies.

## Process of simplification
We will pick each of our actions, types, reducer(s) and simplify them one by one.

### Actions and Types
This is how we write our actions and types in this approach

{% gist https://gist.github.com/sunil12738/619ecd3b69c32903795d1868972ac306 %}

Observe here that there are 3 actions and 3 types. And the same pattern will be repeated for each API call. Imagine if there are 10 API calls. It means there will be 30 actions and 30 types to be manually written. To avoid this, we will write a helper function that will take one input string and return all the these. The function will look something like this:

{% gist https://gist.github.com/sunil12738/16184e302a0fa509e170feb8dcf6f491 %}

If we use the above function then the entire logic for actions and types will be reduced to just one single line

```javascript
const getUsersList = actionCreator('GET_USERS_LIST')
```

This will give all the required actions and types.
Next question is how to use all these. The answer is pretty simple. getUsersList is an object, so the relevant actions and types will be following:

- getUsersList.request *instead of* getUsersListRequest
- getUsersList.success *instead of* getUsersListSuccess
- getUsersList.failure *instead of* getUsersListFailure
- getUsersList.REQUEST *instead of* GET_USERS_LIST_REQUEST
- getUsersList.SUCCESS *instead of* GET_USERS_LIST_SUCCESS
- getUsersList.FAILURE *instead of* GET_USERS_LIST_FAILURE

## Reducer

This is how current reducer looks like and it is only usable for one api call.

{% gist https://gist.github.com/sunil12738/9f47d3141c9770ca9789932f370c731c %}

The reducer will now be modified to this

{% gist https://gist.github.com/sunil12738/d307a238de1be17e020a61fdbbca2e8c %}

Note we have done 2 things here:
- We have clubbed the relevant switch cases together and transferred the logic to update store to a new **reducerHandler** function.
- We have added a key `usersList` which will contain entire state for that particular API. This will make sure that same reducer can be used for multiple API calls.

Let see the definition of `reducerHandler` function (helper function to be written only once) now:

{% gist https://gist.github.com/sunil12738/ae589f43fea64f56ea68c5b1421444a8 %}

Though we have added few functions which might seem that code is increased but observe that the task of creating multiple actions, types and reducers is reduced to few lines. Now if we have to do a new API call, just one line is added to create actions & types and few lines added in reducers instead of writing about 50 lines and adding a new reducer. This simplifies the code a lot. 

### Integrating with middlewares
The other part of calling from sagas and dispatching actions will remain same. Let's see an example:

{% gist https://gist.github.com/sunil12738/08a36d155de7d4133e061319ca4ca4b9 %}

This will help to keep code clean and help developers to increase productivity and focus on other areas.

## Exhaustive example
Just to show, how this approach works here is an example with just 3 API calls:

### Old approach ([read more here](https://dev.to/sunil12738/using-request-success-failure-pattern-in-redux-to-handle-async-actions-4d0))
{% gist https://gist.github.com/sunil12738/8d9c017a785f9aa9282066afce634a5a %}

### Simplified new approach
{% gist https://gist.github.com/sunil12738/c1116f97e4494ca72e6cca1cc7bc4f8b %}
If you see, effort is almost reduced to 1/3rd with same desired effect.

Are we done? Yes! At this point, a lot of repetitive logic is reduced and code is simplified. Can we simplify this further? Maybe, but I won't advice it. We can even write a wrapper to avoid writing actions and reducers at all but it has chances of doing more harm than good. 

## Are there any libraries which can provide these utilities?
Yes, there are a few libraries which can do this for you but one should always think before adding extra libraries. Libraries increase the bundle size and then one has to maintain dependencies etc. That's why for simpler parts like this, writing our own logic seems preferable.

Hope, you like this article. Please like, share and comment to discuss anything which can make this approach better.

____________