user11038307
user11038307

Reputation:

How to get all api response (33) in one place without making a mess

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

Answers (1)

arizafar
arizafar

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

Related Questions