I’m working with eBay API and in particular a GetMultipleItems call which feeds the api query with a list of item ID’s to return data. The problem i’m facing is that the API has a limit per query of 20 item id’s. I’m making call in my backend in node and returning the data via React and Redux.
This is where i make the call to my action creator in React front end.
useEffect(() => {
props.getUpdates(formatFavs);
}, [props.favorites]);
Note that formatFavs
is a list of comma separated itemID’s
Here is my getUpdates action creator
export const getUpdates = id => {
return async dispatch => {
const updates = await dataService.getMultiple(id);
dispatch({
type: "GET_DATA",
data: updates
});
};
};
Which is pointing to my axios call to the backend.
const getMultiple = query => {
const request = axios.get(baseUrl + `?id=${query}`);
console.log("URL", baseUrl + `?id=${query}`);
console.log("Request", request);
return request.then(response => response.data);
};
This is what the resulting call looks like
https://open.api.ebay.com/shopping?callname=GetMultipleItems&appid=XX&responseencoding=JSON&ItemID=231560863628,223787055529,392521444227,352879382550,274129160671,274129160671,274129160671,123998356843,223787055529,383011548243,223787055529,392521444227,352879382550,123998356843,274129160671,133268486829,223787404912
‘
Currently if there are more than 20 id’s it generates an error on the API end.
I need to figure out how to handle any situation where there are more than 20 id’s
My initial line of thinking is to put a conditional statement at the start of my getMultiple
call.
something like
if query.length >20 {
newQuery = query.slice(1,19)
const request = axios.get(baseUrl + `id=${newQuery}
return request.then(response => response.data)
}
although i’m not sure where to go from here…just looking for some suggestions as I’m struggling to come up with the right solution
UPDATED–got this working based on Kostas guidance. Here is the code:
import axios from "axios";
const baseUrl = "/getMultiple";
async function getMultiple(query) {
if (query.length < 21) {
const request = axios.get(baseUrl + `?id=${query}`);
return request.then(response => response.data);
}
let ids = [...query];
console.log("IDS", ids);
const batchSize = 20;
const requests = [];
while (ids.length) {
let currentBatch = ids.splice(0, batchSize);
console.log("Current batch", currentBatch);
requests.push(axios.get(baseUrl + `?id=${currentBatch}`));
}
console.log("Requests", requests);
const final = await Promise.all(requests);
const finalData = final.map(dataArray => dataArray.data);
const arrayData = Array.prototype.concat(...finalData);
return arrayData;
}
export default {
getMultiple
};
2
Answers
I would break up your calls and group them into a
Promise
array.axios.get
returns aPromise
so you can use that in place of the example function (httpGet(id)
)Basically, create a method to receive n number of favorites. Then, break down your ids into groups of 20 with your
axios
calls. So, if you received 60 ids, you’d end up with 3 api calls (each with 20 ids).You can then get the entire result list in the return of
Promise.all
and concat the array from there (if you need to). Below, I’m not grouping your ids by 20 but rather demonstrating the usage of how you can leveragePromise.all
to send a bunch of and wait for all of them to resolve and do something with that result.You can break the request into multiple batches and use Promise.all() to get back the result as follows: