user393219
user393219

Reputation:

Nesting Callbacks Within Themselves

I think I am looking for a nested callback but I'm really unsure about the terminology or programming methodology to use.

My problem I came across was when I was programming a way to get all results for a specific search with Google Places API.

There's no way for me to know how many results I'll have, so I'll need to loop through a callback if a certain object property exists with the response I get back from Google.

As far as I can tell, I need to check if another page exists, and if so, run the callback again but I'm unsure where to put that call at. It's definitely synchronous as I have to wait for a response to determine whether to run again.

Here's what I've tried so far:

function secondCallback(error, response, body) {
    console.log(JSON.parse(body));
}

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        var results = JSON.parse(body);
        var page_token = results.next_page_token;

        if (page_token) {
            console.log(results);
            console.log('there is another token to run');
            options.url += '&pagetoken='+page_token;
            console.log('with this token:' + options.url);
            request(options, callback); // doesn't work
            callback(); // doesn't work
        } else {
            console.log(results);
            console.log('no more results');
        }
    }
}

request(options, callback);

What's the most terse way to do something like this, assuming I could have a near-infinite number of iterations?

My console looks like this:

...
{ geometry: [Object],
   icon: 'http://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png',
   opening_hours: [Object],
   photos: [Object],
   scope: 'GOOGLE',
   types: [Object],
  status: 'OK' }
there is another token to run
with this token:https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=API_KEY&location=39.0997265,-94.57856670000001&radius=16093.4&keyword=guitar&pagetoken=CoQC9AAAAD8nKIOlABe_PU7NIaHP8320A7oY1avuGKYlpPMhba6HYwQmAhLvaGXPcPOlWK-V4VafGJLTUAmhplf7bvHv__fHSWSkkwvVpBzljntB9hMQIxoUnwZAyi3jU5Cyw2WQ_fZ3AJzLMO9ti_uv_Z2RAnAW694EDMDlyrONRKY3Yjrx0Ri9dJrzP0PWY2AtVJFqsLSquPb8azSnS3gINuCLe-Y5-Q18vq__V6pEuUNSipf_Trww1cGH67Q6oZ0aa6CAmrp8YSOJ7St6O1tmbj_N0gjBuNpqZ-k_YAhL3zeVYNIX8IWC3KHkVZkFAXSlN0RaV0Yd_K0gHpKeJmGLVjH5zlgSEAMR_J112AV2lAC7afssRPYaFFvW3fiySrpMQCsIsGpFSyWvulxm
{ html_attributions: [], results: [], status: 'INVALID_REQUEST' }
no more results

A quick search on Google Places API indicates this response for status: INVALID_REQUEST generally indicates that a required query parameter (location or radius) is missing. However I'm verifying that I'm just sending the request url with &pagetoken=PAGE_TOKEN amended to it.

I've isolated it to these lines (see first code paste):

request('https://maps.googleapis.com/maps/api/place/nearbysearch/json?key='+apiKey+'&location='+latLong+'&radius='+radius+'&pagetoken=CoQC9AAAALHMvGfCqSR3TvplrBKu6Ra7YQXS1TpteDN0Cd_9HuyGUa1v7lFbFdCkezzqtG02CKBAkYpp1_VgOtz6Eu6ivKtsEsKNiHGj2KBvdI7tTZVxz-LZES8nZmcu-dFlDSKYYKVhD00sD26zAASvTGfdZ31wX62DesBxeI6TyPP3Zh6I_IW3W2yvUNZJ0hUNyZX-6t03YEDwacUw7oUL_gueOlkIIB93C4X0-zRyBFjzFUmAtzu45MXjINQ9RwHwlZnLqBqeKEhuWaTXBpxfkE1dQuuH4fIqBI-Ytnj_dDq4J1xhNav1Qk0BYo59PPqFVquWRI_KrJzm5fo11n4SeqAj_-4SEGMXaSFnDegQ5zWI-7qip4waFBj6NGnjVeXIjxTo3KpN4EdmigEa', secondCallback); // works
        console.log(pageToken); // is what it should be
        request('https://maps.googleapis.com/maps/api/place/nearbysearch/json?key='+apiKey+'&location='+latLong+'&radius='+radius+'&pagetoken='+pageToken, secondCallback); // seems to be a proper string

Upvotes: 0

Views: 71

Answers (1)

istos
istos

Reputation: 2662

Here is a simple example that uses jQuery where on every Ajax success we make another Ajax call if our data has a next_page_url property.

function out(str) {
  $(document.createElement('h2'))
    .text(str)
    .appendTo(document.body);
}

function error(err, errText) {
  console.log('ERROR: ', errText);
}

function success(data) {
  if (data) {
    if(data.next_page_url) {
      // Make another request if our data has another URL
      request(data.next_page_url);
    }

    out(data.title);
  }
}

function request(url) {
  return $.ajax({
    url: url,
    dataType: 'json'
  })
  .done(success)
  .fail(error);
}

request('http://jsbin.com/fohozupaqi/1.json');

The URLs we're requesting are:

Here is a live example: http://jsbin.com/cecafiqexo/1/edit?html,js,output

I hope it helps!

Upvotes: 1

Related Questions