title: How to use an RxJava Observer to get an ArrayList of restaurants using Google Map and the NearbySearch Api?
body: <p>I have a program that makes queries to Google Map NearbySearch Api, to get all restaurants around a given location.
  As the server returns up to 3 pages, each containing 20 results, I have to run 3 queries, according to the fact that a given Json attribute is set, named next_page_token.
  The starting point is the method named getResto
  After each query returns, I store the list of restaurants in an ArrayList, named restos.
  My problem is, how to get the restos ArrayList, filled with restaurants.
  The following way of doing is not correct, as the getResto() method returns immediately, and the ArrayList is empty.</p>
  <pre><code>public List&lt;PlaceNearbySearchPlace&gt; getAllRestos() {
      getResto();
      return restos;
  }
  </code></pre>
  <p>I guess I should use an Observable, waiting for all queries to complete.
  How would you do that??</p>
  <p>Here is my program</p>
  <pre><code>public class RestoRepository {
      private final String TAG = &quot;RestoRepository&quot;;
      private final String ESTABLISHMENT_TYPE = &quot;restaurant&quot;;
      private final String GOOGLE_MAP_API_KEY = &quot;YOUR_KEY&quot;;
      private final CompositeDisposable disposable = new CompositeDisposable();
      private String mNextPageToken = null;
      //
      private String location = &quot;48.854685336064264, 2.3467574997969596&quot;; // chatelet
      private int radius = 1500;
      private int THREAD_SLEEP=2000;
      // an ArrayList to store restaurants
      List&lt;PlaceNearbySearchPlace&gt; restos;
  
      // CTor
      public RestoRepository() {
          restos = new ArrayList&lt;&gt;();
      }
  
      public List&lt;PlaceNearbySearchPlace&gt; getAllRestos() {
          // getResto returns immediately,
          // and getAllRestos returns an empty list.
          getResto();
          return restos;
      }
  
  
      // search for the list of the 20 first restaurants
      private Observable&lt;PlaceNearbySearch&gt; streamFetchRestaurants(String location, int radius, String type) {
          RestoApi restoApi = RetrofitBuilder.getRetrofit().create(RestoApi.class);
          return restoApi.getRestoFirstPage(location, radius, type, GOOGLE_MAP_API_KEY)
                  .subscribeOn(Schedulers.io())
                  .observeOn(Schedulers.io())
                  .timeout(10, TimeUnit.SECONDS);
      }
  
      // search for the next page
      private Observable&lt;PlaceNearbySearch&gt; streamFetchRestaurantsNextPage(String location, int radius, String type, String pageToken) {
          RestoApi restoApi = RetrofitBuilder.getRetrofit().create(RestoApi.class);
          return restoApi.getRestoNextPage(location, radius, type, pageToken, GOOGLE_MAP_API_KEY)
                  .subscribeOn(Schedulers.io())
                  .observeOn(Schedulers.io())
                  .timeout(10, TimeUnit.SECONDS);
      }
  
      // get the list of the first 20 restaurants
      public void getResto() {
          Log.d(TAG, &quot;getResto: enter&quot;);
          streamFetchRestaurants(location, radius, ESTABLISHMENT_TYPE)
                  .subscribe(new Observer&lt;PlaceNearbySearch&gt;() {
                      @Override
                      public void onSubscribe(@NonNull Disposable d) {
                          disposable.add(d);
                      }
  
                      @RequiresApi(api = Build.VERSION_CODES.N)
                      @Override
                      public void onNext(@NonNull PlaceNearbySearch placeNearbySearch) {
                          mNextPageToken = placeNearbySearch.getNext_page_token();
                          Log.d(TAG, &quot;getResto#onNext: mNextPageToken: &quot; + mNextPageToken);
                          Log.d(TAG, &quot;getResto#onNext: nb of resto: &quot; + placeNearbySearch.getResultSearches().size());
                          placeNearbySearch.getResultSearches().forEach(place -&gt; {
                              Log.d(TAG, &quot;getResto#onNext: place: &quot; + place.getName());
                              restos.add(place);
                          });
                          Log.d(TAG, &quot;getResto#onNext: restos.size(): &quot; + restos.size());
                      }
  
                      @Override
                      public void onError(@NonNull Throwable e) {
                          Log.d(TAG, &quot;onError: &quot; + e.getMessage());
                      }
  
                      @Override
                      public void onComplete() {
                          try {
                              // Is there an extra page?
                              if (mNextPageToken != null) {
                                  // There is a short delay between when a next_page_token is issued,
                                  // and when it will become valid
                                  Thread.sleep(THREAD_SLEEP);
                                  getSecondPage();
                              }
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                  });
      }//getResto
  
      public void getSecondPage() {
          Log.d(TAG, &quot;getSecondPage: mNextPageToken: &quot; + mNextPageToken);
          streamFetchRestaurantsNextPage(location, radius, ESTABLISHMENT_TYPE, mNextPageToken)
                  .subscribe(new Observer&lt;PlaceNearbySearch&gt;() {
                      @Override
                      public void onSubscribe(@NonNull Disposable d) {
                          disposable.add(d);
                      }
  
                      @RequiresApi(api = Build.VERSION_CODES.N)
                      @Override
                      public void onNext(@NonNull PlaceNearbySearch placeNearbySearch) {
                          mNextPageToken = placeNearbySearch.getNext_page_token();
                          Log.d(TAG, &quot;getSecondPage#onNext: mNextPageToken: &quot; + mNextPageToken);
                          Log.d(TAG, &quot;getSecondPage#onNext: nb of resto: &quot; + placeNearbySearch.getResultSearches().size());
                          placeNearbySearch.getResultSearches().forEach(place -&gt; {
                              Log.d(TAG, &quot;getSecondPage#onNext: place: &quot; + place.getName());
                              restos.add(place);
                          });
                          Log.d(TAG, &quot;getSecondPage#onNext: restos.size(): &quot; + restos.size());
                      }
  
                      @Override
                      public void onError(@NonNull Throwable e) {
                          Log.d(TAG, &quot;getSecondPage#onError: &quot; + e.getMessage());
                      }
  
                      @Override
                      public void onComplete() {
                          try {
                              // Is there an extra page?
                              if (mNextPageToken != null) {
                                  Thread.sleep(THREAD_SLEEP);
                                  getThirdPage();
                              }
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
  
                  });
      }//getSecondPages
  
      // the servers returns a max of 60 results.
      public void getThirdPage() {
          Log.d(TAG, &quot;getThirdPage: mNextPageToken: &quot; + mNextPageToken);
          streamFetchRestaurantsNextPage(location, radius, ESTABLISHMENT_TYPE, mNextPageToken)
                  .subscribe(new Observer&lt;PlaceNearbySearch&gt;() {
                      @Override
                      public void onSubscribe(@NonNull Disposable d) {
                          disposable.add(d);
                      }
  
                      @RequiresApi(api = Build.VERSION_CODES.N)
                      @Override
                      public void onNext(@NonNull PlaceNearbySearch placeNearbySearch) {
                          mNextPageToken = placeNearbySearch.getNext_page_token();
                          Log.d(TAG, &quot;getThirdPage#onNext: mNextPageToken: &quot; + mNextPageToken);
                          Log.d(TAG, &quot;getThirdPage#onNext: nb of resto: &quot; + placeNearbySearch.getResultSearches().size());
                          placeNearbySearch.getResultSearches().forEach(place -&gt; {
                              Log.d(TAG, &quot;getThirdPage#onNext: place: &quot; + place.getName());
                              restos.add(place);
                          });
                          Log.d(TAG, &quot;getThirdPage#onNext: restos.size(): &quot; + restos.size());
                      }
  
                      @Override
                      public void onError(@NonNull Throwable e) {
                          Log.d(TAG, &quot;getThirdPage#onError: &quot; + e.getMessage());
                      }
  
                      @Override
                      public void onComplete() {
                          Log.d(TAG, &quot;getThirdPage#onComplete: completed&quot;);
                      }
                  });
      }//getThirdPage
  }
  </code></pre>
  <p>Here is the retrofit interface</p>
  <pre><code>public interface RestoApi {
  
      @GET(&quot;nearbysearch/json&quot;)
      Observable&lt;PlaceNearbySearch&gt; getRestoFirstPage(@Query(&quot;location&quot;) String location,
                                                      @Query(&quot;radius&quot;) int radius,
                                                      @Query(&quot;type&quot;) String type,
                                                      @Query(&quot;key&quot;) String key);
  
      @GET(&quot;nearbysearch/json&quot;)
      Observable&lt;PlaceNearbySearch&gt; getRestoNextPage(@Query(&quot;location&quot;) String location,
                                                     @Query(&quot;radius&quot;) int radius,
                                                     @Query(&quot;type&quot;) String type,
                                                     @Query(&quot;pagetoken&quot;) String nextPageToken,
                                                     @Query(&quot;key&quot;) String key);
  }
  </code></pre>
  <p>Thanks in advance...</p>