I am working with an API in an Angular NGRX app that requires I make multiple calls to get all the data I'm looking for. For example, I start off by requesting a list of groups
GET http://api-path/my/groups
That returns an array of id
objects, like this:
[
{
"id": "MDJiZDlmZDYtOGY5My00NzU4LTg3YzMtMWZiNzM3NDBhMzE1IyNkMmM2ZjExMS1mZmFkLTQyYTAtYjY1ZS1lZTAwNDI1NTk4YWE="
},
{
"id": "MDJiZDlmZDYtOGY5My00NzU4LTg3YzMtMWZiNzM3NDBhMzE1IyMxNGQ2OTYyZC02ZWViLTRmNDgtODg5MC1kZTU1NDU0YmIxMzY="
},
{
"id": "MDJiZDlmZDYtOGY5My00NzU4LTg3YzMtMWZiNzM3NDBhMzE1IyMyMGMzNDQwZC1jNjdlLTQ0MjAtOWY4MC0wZTUwYzM5NjkzZGY="
},
{
"id": "MDJiZDlmZDYtOGY5My00NzU4LTg3YzMtMWZiNzM3NDBhMzE1IyMyYTg0OTE5Zi01OWQ4LTQ0NDEtYTk3NS0yYThjMjY0M2I3NDE="
},
{
"id": "MDJiZDlmZDYtOGY5My00NzU4LTg3YzMtMWZiNzM3NDBhMzE1IyMzNGIwMTg1MS1jMTNkLTQ2MDQtYmIzYi01ZGUxZWNiZjAyODg="
},
{
"id": "MDJiZDlmZDYtOGY5My00NzU4LTg3YzMtMWZiNzM3NDBhMzE1IyM1YWY2YTc2Yi00MGZjLTRiYTEtYWYyOS04ZjQ5YjA4ZTQ0ZmQ="
},
{
"id": "MDJiZDlmZDYtOGY5My00NzU4LTg3YzMtMWZiNzM3NDBhMzE1IyM4NmZjZDQ5Yi02MWEyLTQ3MDEtYjc3MS01NDcyOGNkMjkxZmI="
},
]
I then have to make a call for each id
object to get the details:
GET http://api-path/group/{ID}
I'm currently using an effect to trigger these calls:
loadGroupSuccess = createEffect(() =>
this.actions$.pipe(
ofType(fromActions.loadGroupSuccess),
delay(this.debounceTime(), asyncScheduler),
filter(({ group }) => !!team),
mergeMap(({ group }) => [
...group.map((id) =>
fromActions.loadGroupDetails({ id })
),
])
)
);
The loadGroupDetails
action is received by another effect and makes the call out to the API. I'm currently injecting a random delay between 0-500ms with the this.debounceTime()
function. If I don't put that in, all of the XHR requests happen at the same time and the browser becomes locked while the data is downloaded.
I feel like there is a better way to handle something like this. Is there a way to stagger the requests so that only a few happen at a time? Is there a better way to call out to these APIs than using effects?
There is a concurrency param you can set in mergeMap
which can improve your performance,
mergeMap(getHttp, 3)
In this case, maximum 3 calls concurrently made at any given time