Reputation:
Help me to deal with horrible structured API.
So here is response if I'll make one call to API with params: region
: 'eu', period
: 'may'
{
users: {
'idHERE1': {
server: 'EU',
period: 'may',
data1: 1111,
data2: 4535
},
'idHERE2': {
server: 'EU',
period: 'may',
data1: 5235,
data2: 5325
}
}
}
and I want something like this in a end:
[
{
id: 'idHERE1',
may: {
servers: {
eu: {
data1: 1111,
data2: 4535
},
na: {
data1: 7236
data2: 24
}
}
},
june: {
servers: {
eu: {
data1: 5235,
data2: 14
},
na: {
data1: 667
data2: 124
}
}
},
july: {
servers: {
eu: {
data1: 62,
data2: 6145
},
na: {
data1: 725
data2: 12174
}
}
}
}
// same for "idHERE2"
]
// etc
To do so I need to make 33 requests to the API.
There are 3 regions: 'eu', 'na', 'asia'.
period = month, so right now there are 11 of them but it's growing every month.
And I can't figure out how to code it so it wouldn't be a big mess.
I tried so far:
const servers = ['eu', 'na', 'asia'];
const promise = servers.map(s =>
fetch(`apiURL.com/opts?server=${s}`)
.then(r => r.json())
);
Promise.all(promise)
.then(res => {
// do stuff
});
it work and I got what I wanted all I had left is to format it with reduce
and etc, but then I decided to put promise inside another map with periods
const promise = periods.map(p =>
servers.map(s =>
fetch(`apiURL.com/opts?server=${s}?period=p`)
.then(r => r.json())
)
)
I got that:
[
[
Promise [Object] {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined
},
Promise [Object] {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined
},
Promise [Object] {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined
}
],
[
Promise [Object] {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined
},
Promise [Object] {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined
},
Promise [Object] {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined
}
]
]
So I'm not sure if Promises is way to go or there is better way to do it.
Upvotes: 1
Views: 69
Reputation: 3122
You just need to wait for the promises returned from the loop
const promise = periods.map(p =>
Promise.all(servers.map(s =>
fetch(`apiURL.com/opts?server=${s}?period=p`)
.then(r => r.json())
))
)
return Promise.all(promise);
You can implement async-await which will make your code more readable also better error handling, but that also includes the use of promises, so you are good to go with the implemented code.
Also If you want to hit all the API's together you can flatten the array and then use Promise.all
const promise = [].concat(...periods.map(p =>
servers.map(s =>
fetch(`apiURL.com/opts?server=${s}?period=p`)
.then(r => r.json())
)
))
return Promise.all(promise);
Upvotes: 1