Reputation: 133
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
Reputation: 2093
panoProvider
is not supposed to be called asynchronously. That means you have to have all necessary information for creating custom StreetViewPanorama
s 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
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