Javascript Function Variables - javascript

What do the variables result and status refer to in this? Where do they come from? How does origin, destination and travel mode get passed into the function? Where does the result of the function go?
$('#directions-form').submit(function(e) {
$('#error').hide();
ds.route({
origin: $('#from').val(),
destination: $('#to').val(),
travelMode: $('#mode').val()
}, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
fitBounds = true;
dr.setDirections(result);
}
else {
$('#error').text(status).show();
}
recalcHeight();
});
e.preventDefault();
return false;
});

They are the parameters of the success callback function.
route method when invoked with proper variables fires the callback asynchronously when the response is a success. The parameters are part of the callback as part of the method invocation.
So you can go ahead and replace them with any variable name you want which will can be used inside the function closure.
}, function(a, b) { // Will work to

This function is being called with two parameters:
ds.route()
The first parameter is an object with some values in it:
{
origin: $('#from').val(),
destination: $('#to').val(),
travelMode: $('#mode').val()
}
The second parameter is a function:
function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
fitBounds = true;
dr.setDirections(result);
}
else {
$('#error').text(status).show();
}
recalcHeight();
}
Note that in JavaScript a function is an object like any other, and can be passed around like a variable. Since it's being passed into ds.route() as a variable, the function itself isn't being executed yet.
Internally, ds.route() is using the first parameter which has the values (origin, destination, travelMode) to do, well, something. It doesn't matter what, it's just whatever that function does.
Then, when it's done, it's going to execute the second parameter, which is the function. When it executes that function, it's going to pass two values into it as parameters. Those values will end up being the result and status variables used within the function.
To illustrate, you could do something as simple as this:
function doSomething(value, callback) {
if (value == 1) {
alert("The value is 1");
callback(2)
}
}
doSomething(1, function (value) {
if (value == 2) {
alert("The value is 2");
}
});
This defines a function which takes two arguments, and expects them to be a number and a function. If the number equals 1, it executes that function. This function is then called with the value 1 and a function, which will be executed as a callback.

When ds.route is called with route object as it's sole argument, it generates a result and a status. These are passed as the arguments to its callback.

Related

return success data in require.js with callback

i have a little understanding problem with my current code...
i create a new require js module.
define(['jquery','apiomat'],function($,Apiomat) {
var getLocation = function(data, callback) {
Apiomat.Localization.getLocalizations("locale like 'de'", {
data: data,
onOk: function (data) {
callback(data);
}
});
};
return {
getData: function(data, callback) {
getLocation(data, callback);
}
}
});
And if i try to access these function with:
var test = easy.getData();
app.logger("CALLBACK FROM COMMON: " + JSON.stringify(test));
I always get this error message.
TypeError: callback is not a function. (In 'callback(data)', 'callback' is undefined)
Im not really sure what i have done wrong.
getData takes two arguments. The second one is supposed to be a function, but you aren't passing any arguments at all, so it gets the value undefined.
It then calls getLocation with the same arguments and Apiomat.Localization.getLocalizations does its thing. Eventually getLocalizations (or another function called by it) calls getOK which attempts to call callback.
undefined is not a function, so you get the error message.
Additionally the getData function doesn't have a return statement so will be returning undefined. This means there is no point in assigning the return value to test.
You need to pass a function which does whatever you want to do:
function myCallback(test) {
app.logger("CALLBACK FROM COMMON: " + JSON.stringify(test));
}
… and pass arguments to getData.
easy.getData("some data", myCallback);

Best way to 'return true' based on conditions from nested functions

This may be a novice question but I am trying to create a function that returns true. However, this is based on what happens within several other functions inside.
function checkGeo(){
// CHECK FOR GEOLOCATION
if( "geolocation" in navigator ) {
navigator.geolocation.getCurrentPosition( function(position){
sessionStorage.pinlat = position.coords.latitude;
sessionStorage.pinlon = position.coords.longitude;
// position object is set!
});
// position is not defined
if ( position.coords.latitude && position.coords.longitude ){
return true;
}
}
}
This is the order I want things to happen with my geolocation check but I'm a bit surprised that the nested if is tested before the getCurrentPosition method finishes.
Putting this condition within the getCurrentPosition success function and returning true from there does not make checkGeo return true. How do I check if this asyncronous function has ended and therefore check its results in order to return true?
Have your function have a finished variable
function checkGeo(){
var self = this;
this.ready = function () {}
this.result = false;
if("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(function(position) {
sessionStorage.pinlat = position.coords.latitude;
sessionStorage.pinlon = position.coords.longitude;
self.result = (position.coords.latitude && position.coords.longitude);
self.ready.call(self);
});
}
}
Now you can use the function:
var run = new checkGeo();
run.ready = function () {
alert(this.result); //Both work
alert(run.result); //Both work
};
A bit more complicated, but better programming in my opinion.
position in the anonymous function is not the same as position in the if statement after it. Scope in JavaScript (ignoring ES6 let keyword for simplicity) is by function.
Additionally, if getCurrentPosition() is asynchronous, then you can't rely on the anonymous callback function to run before anything else.
If all you want the return true to signify is that you are trying to get geolocation info without any guarantee that you will be successful, use something more like this:
function checkGeo(){
var hasGeolocation = false;
// CHECK FOR GEOLOCATION
if( "geolocation" in navigator ) {
hasGeolocation = true;
navigator.geolocation.getCurrentPosition( function(position){
sessionStorage.pinlat = position.coords.latitude;
sessionStorage.pinlon = position.coords.longitude;
// position object is set! but only inside this function.
});
return hasGeolocation;
}
}
On the other hand, if you are trying to have return true indicate that the geolocation was successfully set, then you need to indicate it some other way than the return value of the synchronous function, because you won't know that it will be set (an error might occur, a user might disallow geolocation for your site etc.) until the asynchronous function invokes the callback.
The geolocation call is asynchronous, so you can't return the result from the function. When the function ends, you don't yet know the result from the asynchronous call. Returning anything from the callback for the asynchronous call won't make that the return value of the function, because the function has already returned.
You can use callback to report the result back. You have to use the code that checks the position in the callback for the asynchronous call:
function checkGeo(callback){
if( "geolocation" in navigator ) {
navigator.geolocation.getCurrentPosition(function(position){
sessionStorage.pinlat = position.coords.latitude;
sessionStorage.pinlon = position.coords.longitude;
callback(position.coords.latitude && position.coords.longitude);
});
} else {
callback(false);
}
}
Usage:
checkGeo(function(exists){
// here you can use the result
if (exists) {
// ...
}
});

How to resolve a Javascript Scope issue. Is closure the answer? [duplicate]

This question already has an answer here:
Saving geocoder results to an array - Closure Trouble
(1 answer)
Closed 9 years ago.
I have a function
function getCustomAddress() {
alert(results[i].formatted_address)
}
alert(results[i].formatted_address) is defined in another function. It clearly means that it is undefined in getCustomAddress, so how do I resolve this issue and alert the values. I have set up a fiddle as well.
http://jsfiddle.net/KEdrq/5/
You could just pass it as a function parameter
function getCustomAddress(result) {
alert(result.formatted_address)
}
so when you call the function you need to supply one parameter:
getCustomAddress(results[i]); for example
You could create a private scope with a function and define all your global variables there:
(function(){
var results = [];
function getCustomerAdress(){
//... call result etс
}
function set result(){
//... set result etc
}
// some code for initialization, setting onload handlers etc
})();
I checked out the jsFiddle, the results are fetched as an ajax request.
You need to store the results in a variable with a global scope and then set a timeout to fetch the result. You can also execute your function before the end of geocoder request and pass it the results variable.
geocoder.geocode(geocoderRequest, function (results, status) {
// execute your function here. getCustomAddress(result)
}
Check the changes I have made.
http://jsfiddle.net/KEdrq/7/
Summary of code changes.
var _results;
function initialize() {
.
.
.
google.maps.event.addListener(marker, 'dragend', function (e) {
getAddress(e.latLng);
setTimeout('getCustomAddress(0);', 500);
})
function getAddress(latLng) {
if (!geocoder) {
geocoder = new google.maps.Geocoder();
}
var geocoderRequest = {
latLng: latLng
}
geocoder.geocode(geocoderRequest, function (results, status) {
_results = results;
.
.
.
function getCustomAddress(i) {
alert(_results[i].formatted_address)
}
You might want to create a for loop to alert all the results instead of passing the result id in the getCustomAddress function.

Strange "Undefined variable" in a JavaScript piece of code

I'm a c++ programmer so the following undefined variable error in java script is strange for me. I've defined a global variable ,directionResult and the following code initializes its value :
function calcRoute() {
var iMap = {
departure:"tiran,esfahan",
destination:"esfahan"
}
var request = {
origin : iMap.departure,
destination : iMap.destination,
travelMode : google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
document.getElementById("log").innerHTML = result.routes[0];
directionResult = result;
}
});
}
in the last if directionResult will be equal to result which is a parameter to a call-back function. But in another function :
function showSteps() {
var myRoute = directionResult.routes[0].legs[0];
var point = myRoute.steps[index].start_point;
var inst = myRoute.steps[index++].instructions;
obj.setPosition(point);
document.getElementById('inst').innerHTML = inst;
map.panTo(point);
if (index >= myRoute.steps.length)
clearInterval(timer);
}
when I want to use directionResult at the first line,I encounter this error:
TypeError: directionResult is undefined
How can I solve this strange behavior?thanks.
One possible reason directionResult is undefined may be because you are trying to reference it before it has been set. Although your showSteps() function appears after the calcRoute() function, directionResult is not set until the directionsService.route() callback is fired, which happens (presumably) after an AJAX request.
Try calling showSteps() from within the directionsService.route() callback function instead.

Javascript callback - how to return the result?

I am struggling to totally understand callbacks and i am stumbling at the final hurdle.
Within JS I am calling a function which then calls a PHP function using a dojo rpc Json Service. I have stepped through the function in firebug and the PHP is executing and returning me the correct response via the callback but I don’t know how to return the value to the initial JS variable that invoked the JS function? E.g.
JS Function 1
Function one(){
Var test = getPhp(number);
}
function getPhp(number)
{
this.serviceBroker = new dojo.rpc.JsonService(baseUrl + '/index/json-rpc/');
var result = serviceBroker.phpFunc(number);
result.addCallback(
function (response)
{
if (response.result == 'success')
{
return response.description;
//I am trying to pass this value back to the
//var test value in function one
}
}
);
}
Basically i now need to pass response.description back to my var test variable in function one.
Any help is appreciated
This is not possible, since the callback is run asynchronously. This means that the getPhp function returns before the callback is executed (this is the definition of a callback, and one of the reasons asynchronous programming is hard ;-) ).
What you want to do is create a new method that uses the test variable. You need to call this method when the callback is executed.
i.e.
function one(result) {
var test = result;
// Do anything you like
}
function getPhp(number, callback) {
this.serviceBroker = new dojo.rpc.JsonService(baseUrl + '/index/json-rpc/');
result.addCallback(
function (response)
{
if (response.result == 'success')
{
callback(response.description);
}
}
);
}
getPhp(number, function(result) { one(result); });
This last method creates an 'anonymous function' that is passed to the getPhp function. This function gets executed at the time the response arrives. This way you can pass data to the one(number) function after the data arrives.
The short answer is that you can't.
Do whatever you want to do with the data in the callback or functions you call from the callback. You can't return anything from it.
A much cleaner answer:
getPhp(number);
function one(data){
var test = data;
// do what you want
}
function getPhp(number)
{
this.serviceBroker = new dojo.rpc.JsonService(baseUrl + '/index/json-rpc/');
var result = serviceBroker.phpFunc(number);
result.addCallback(
function (response)
{
if (response.result == 'success')
{
one(response.description);
}
}
);
}

Categories