Multi-Async Requests in One Submit Handler
Tags: asyn, fetch, onsubmit
Published: 2023-11-05 15:53:28

The more I coded the more in depth my applications became.  As they grew in complexity I had a problem caused by an action by a user needing to alter more than one database record.  It seemed straightforward at first, but I realized this may become an issue as the application scales.  What if one request to the api completes, but another fails?  The application needs to be efficient and as concurrent as possible when it comes to handling requests from the user.  I found the Promise.all() method to be the best way to create an all or nothing way for sending my fetch requests.

Because of how applications can develop and grow almost exponentially, handling multiple API requests will be necessary.  The issue doesn't get better because the more complex your application becomes, the more likely you will find yourself needing multiple requests to complete one user action.  Lots of data in an application relies on other data so more concurrent you can get requests the better.  The less concurrent they are the more likely a computer is to misprocess the code and give you an undesired response.

This is where I found value in the Promise.all method. The method will take an iterable (ex. list or array of fetch requests) and will perform them all.  It will only execute the following code (ex. then statements) after all the requests get handled successfully.  It will send multiple promises and only go to the next code once they have all been met.  This works very well for asynchronous requests. Especially if they need to be performed together or when they all need to be completed or none at all.  Here is a basic example:

![phase4a](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3g89gb71503d2zgiqcwi.png)

In this example the onSubmit is given an array of 2 fetch requests with both sent to different routes.  Each end with a then statement converting the response to json.  If both both back successfully an array is returned with each index corresponding to the index of the original array of requests.  In this example I named them according to the data the represented.  Then final then statement takes that array of data and sends to various functions that control state. In this case it updates a client and a user, as well as minimizing the expanded client.  If both or one of the requests failed it would be caught it the final catch statement and set the error to be displayed.

I use a custom Error component that will take an error (that is set in state).  I put that component strategically in various components the user would be viewing so they can see the result right in front of them.

The use of all concurrent requests being handled successfully is important.  Using my case for an example the two fetch requests sent are used to:

1. Lower the client's debt
2. Increase the user's earnings

You can see that if only one of the requests came back successfully and not the other would be detrimental to the data's integrity.  If the request made to the client was successful, but not the user then the client's records would show that they owe less than what they actually do and the user never got paid accurately.  Or in reverse, the user would have a record of being paid, but the client would show that they still owe the full balance.  Instead of corrupting the data it will catch an error if either of the promises doesn't complete.

This can be very useful the more complex your code becomes.  Especially when they one request interacts with multiple routes or tables in your database.

Hopefully this will help you manage multiple asynchronous requests in your future applications and help them to appear more concurrently.