Sam
Sam

Reputation: 3

How to loop depending on amount of results returned in ruby

I'm trying to make it so i can obtain all the information from an api. I need to loop the api calls until i receive less than 1000rows. the problem is the api only returns 1000 rows and i have no idea how many rows it can send, i can however offset each api call.

I'm trying to make it so that the API is called several times and returns everything. below is what I have worked out so far.

  response1 = External::getdataApi.call({country_ids: 'gb', extras: 'hotel_info'})
  response1 = response1.instance_variable_get(:@response)
  if response1['result'].count == 1000
    response1 = External::getdataApi.call({country_ids: 'gb', extras: 'hotel_info', offset: 1000})
  end

What needs to happen is once it's called, it needs to then recall again until its less than 1000 results. At which point the remaining rows are saved and then it breaks out of the loop.

Upvotes: 0

Views: 173

Answers (2)

Paulo Belo
Paulo Belo

Reputation: 4447

You can use a while loop, like this:

offset = 0
end_reached = false

while !end_reached
    response1 = External::getdataApi.call({country_ids: 'gb', extras: 'hotel_info', offset: offset})
    response1 = response1.instance_variable_get(:@response)

    # increase offset by 1000
    offset += 1000

    # if result count is different from 1000 means the end was reached, set end_reached var to true so loop ends
    end_reached = true if response1['result'].count != 1000
end

or an until loop like this:

offset = 0
end_reached = false

until end_reached
    response1 = External::getdataApi.call({country_ids: 'gb', extras: 'hotel_info', offset: offset})
    response1 = response1.instance_variable_get(:@response)

    # increase offset by 1000
    offset += 1000

    # if result count is different from 1000 means the end was reached, set end_reached var to true so loop ends
    end_reached = true if response1['result'].count != 1000
end

I prefer the last one because I think it reads better

Upvotes: 0

Gavin Miller
Gavin Miller

Reputation: 43825

You can use the upto method on Integer to achieve this. Your code would look something like this:

MAX = 100 # or whatever is reasonable
1.upto(MAX) do |index|
  offset = index * 1000
  response1 = External::getdataApi.call({country_ids: 'gb', extras: 'hotel_info', offset: offset})
  response1 = response1.instance_variable_get(:@response)

  # process response

  break if response1['result'].count != 1000
end

Ruby 2.6 also has the concept of infinity and you can instead replace 1.upto(MAX) with: (1..).each if you're using that version.

Upvotes: 1

Related Questions