stml
stml

Reputation: 133

Returning asynchronous results from custom panoProvider

I know there are many, many answers to this question on SO, but I haven't been able to find one that applies in this case. I'm making an asynchronous call to a Google service and need to return the result:

function getCustomPanorama(pano,zoom,tileX,tileY) {
    client.getPanoramaById(pano, function(result, status) {
        return {
            location: result.location,
            links: result.links,
            copyright: result.copyright+' BUT GREY',
            tiles: {
                tileSize: result.tiles.tileSize,
                worldSize: result.tiles.worldSize,
                centerHeading: result.tiles.centerHeading,
                getTileUrl: getCustomPanoramaTileUrl
                }
            };
        });
    }

I understand that the above is wrong and will not return, and think I need to use callbacks, but I don't understand where. Note that I can't change what is passed to getCustomPanorama. All help gratefully received.

UPDATE: Full code:

var panorama;
var client;

$(document).ready(function() {
    var panoramaOptions = {
        position: new google.maps.LatLng(51.52241608253253, -0.10488510131835938),
        panoProvider: getCustomPanorama
        };
    client = new google.maps.StreetViewService();
    panorama = new google.maps.StreetViewPanorama(document.getElementById("pano"), panoramaOptions);
    });

function getCustomPanorama(pano,zoom,tileX,tileY) {
    client.getPanoramaById(pano, function(result, status) {
        return {
            location: result.location,
            links: result.links,
            copyright: result.copyright+' BUT GREY',
            tiles: {
                tileSize: result.tiles.tileSize,
                worldSize: result.tiles.worldSize,
                centerHeading: result.tiles.centerHeading,
                getTileUrl: getCustomPanoramaTileUrl
                }
            };
        });
    }

UPDATE 2:

Suggestions are definitely that I'm trying to do something impossible, so trying another approach involving pre-caching the getPanoramaByID() responses.

Upvotes: 2

Views: 1208

Answers (2)

yatskevich
yatskevich

Reputation: 2093

panoProvider is not supposed to be called asynchronously. That means you have to have all necessary information for creating custom StreetViewPanoramas pre-populated.

But if you really need to call client.getPanoramaById inside of panoProvider then there is a very dirty trick:

function getCustomPanorama(pano,zoom,tileX,tileY) {
  var resultFromAsyncCall;
  client.getPanoramaById(pano, function(result, status) {
    resultFromAsyncCall = {
        ...
        copyright: result.copyright+' BUT GREY',
        tiles: {
          ... 
          getTileUrl: getCustomPanoramaTileUrl
        }
    };
  });

  while (!resultFromAsyncCall) {
    //wait for result
  }   
  return resultFromAsyncCall;
}

BUT, I discourage you from using this solution. Better try to re-think logic of your application.

Related question: Call An Asynchronous Javascript Function Synchronously

Upvotes: 2

Richard Dalton
Richard Dalton

Reputation: 35793

Change getCustomPanorama to take an extra parameter for the callback and pass in a function that does what you needed to do with the result:

function getCustomPanorama(pano,zoom,tileX,tileY,callback) {
    client.getPanoramaById(pano, function(result, status) {
        var data = {
          location: result.location,
          links: result.links,
          copyright: result.copyright+' BUT GREY',
          tiles: {
              tileSize: result.tiles.tileSize,
              worldSize: result.tiles.worldSize,
              centerHeading: result.tiles.centerHeading,
              getTileUrl: getCustomPanoramaTileUrl
          }
        };
        callback(data); // call the function and pass in the data you would have returned
    });
}

getCustomPanorama(pano,zoom,tileX,tileY,function(data) {
    // do something with the results of the asynchronous call here        
});

Upvotes: 2

Related Questions