Reputation: 164
I'm trying to obtain the value of var newtotal from a separate function, which then passes the value on to a PHP script via Ajax.
Here's my code: `
function customerCost(){
var newtotal;
var start = document.getElementById('source').value;
var end = document.getElementById('destination').value;
var via = document.getElementById('via').value;
if(via != ""){
var waypts = [];
waypts.push({
location:via,
stopover:false});
var newrequest = {
origin: start,
destination: end,
waypoints: waypts,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(newrequest, function(newresponse, newstatus) {
if (newstatus == google.maps.DirectionsStatus.OK) {
var newtotal = 0;
var mynewroute = newresponse.routes[0];
for (i = 0; i < mynewroute.legs.length; i++) {
newtotal += mynewroute.legs[i].distance.value;
}
return newtotal;
}
});
}else{
var newrequest = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(newrequest, function(newresponse, newstatus) {
if (newstatus == google.maps.DirectionsStatus.OK) {
var newtotal = 0;
var mynewroute = newresponse.routes[0];
for (i = 0; i < mynewroute.legs.length; i++) {
newtotal += mynewroute.legs[i].distance.value;
}
return newtotal;
}
});
}
}
I am then calling the value from within a separate function with the following:
customertotal = customerCost();
I am only getting an "undefined" error. However if I replace the return newtotal;
for alert(newtotal);
then it outputs the correct value.
Where am I going wrong?
Upvotes: 1
Views: 72
Reputation: 7585
you should use callback function to work with variables inside asynchronous functions.
You can add a callback function as parameter:
customerCost(callback){
// your original code
}
Then replace all line like return newtotal
by callback(newtotal);
Then invoke function customerCost
like:
customerCost(function(customertotal){
// work with customertotal
});
Upvotes: 1
Reputation: 707198
The directionsService.route()
call is asynchronous. That means that when you call it, it only starts the operation and your customerCost()
function continues and finishes long before the .route()
ajax call has finished and called its callback.
You are trying to program in a synchronous fashion with an asynchronous operation. You can't do that. Your customerCost()
function call cannot return the newtotal
value because it isn't known yet at the time that function returns.
Instead, you need to learn how to program in an asynchronous way. Any code that needs the newtotal
value needs to either be in the callback where that value is available or you can call a function from there and pass it the newtotal
value.
A typical way to develop something like this might be with your own callback:
function customerCost(cb){
var newtotal;
var start = document.getElementById('source').value;
var end = document.getElementById('destination').value;
var via = document.getElementById('via').value;
if(via != ""){
var waypts = [];
waypts.push({
location:via,
stopover:false});
var newrequest = {
origin: start,
destination: end,
waypoints: waypts,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(newrequest, function(newresponse, newstatus) {
if (newstatus == google.maps.DirectionsStatus.OK) {
var newtotal = 0;
var mynewroute = newresponse.routes[0];
for (i = 0; i < mynewroute.legs.length; i++) {
newtotal += mynewroute.legs[i].distance.value;
}
// call the callback and pass it the newtotal
cb(newtotal);
}
});
}else{
var newrequest = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(newrequest, function(newresponse, newstatus) {
if (newstatus == google.maps.DirectionsStatus.OK) {
var newtotal = 0;
var mynewroute = newresponse.routes[0];
for (i = 0; i < mynewroute.legs.length; i++) {
newtotal += mynewroute.legs[i].distance.value;
}
// call the callback and pass it the newtotal
cb(newtotal);
}
});
}
}
// call the asynchronous cost function and process the result
// in a callback function
customerCost(function(newtotal) {
// the newtotal value is available here
});
Upvotes: 2