skip to Main Content

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


  1. I would break up your calls and group them into a Promise array. axios.get returns a Promise 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 leverage Promise.all to send a bunch of and wait for all of them to resolve and do something with that result.

    function httpGet(id) {
      return fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
        .then(response => response.json());
    }
    
    function getFavorites(ids) {
      // TODO: Implement logic to group promise array by chunks of 20
      const promises = ids.map(id => httpGet(id));
      return Promise.all(promises);
    
    }
    
    getFavorites([1, 2, 3, 4, 5, 6, 7, 8, 9]).then(results => console.log(results));
    Login or Signup to reply.
  2. You can break the request into multiple batches and use Promise.all() to get back the result as follows:

    async function getMultiple( input ) {
    
        if ( input.length < 21 ){
            return axios.get( baseUrl + `id=${input}` );
        } 
    
        let ids = [ ...input ];
        const batchSize = 20;  
        const requests = [];
    
        while ( ids.length ){
    
            let currentBatch = ids.splice( 0, batchSize );
            requests.push( axios.get( baseUrl + `id=${currentBatch}` ) );    
    
        }
    
        return await Promise.all( requests );
    
    }
    let input = [ 1, 2, 3, 4, ... 24, 25, 25 ];
    
    getMultiple( input ).then( res => console.log(res) );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search