Can't change value of global variable JS - javascript

I have 2 global variables : Lon and Lat
And I want to change the value of these variables inside the function of geolocalisation offered by HTML5:
here is my code :
window.lat={{geo['latitude']}};
window.lon={{geo['longitude']}};
var SK= readCookie('SK');
if(SK==1)
{
navigator.geolocation.getCurrentPosition(function(e){
window.lat=e.coords.latitude;
window.lon=e.coords.longitude;
window.zoomi=15;
})
}
the final value of window .lat is always
window.lat={{geo['latitude']}}
Does anyone know why ?
PS: the SK==1 is true, and inside the function(e), I tried to alert the values and they really change.
but once out of the function, everything vanishes

Javascript is always synchronous and single-threaded so if you are checking window.lat after callback it gets executed even before gelocation call and it has same value.geolocation takes few seconds to get the value and you must write up your code in callback fucntion or write a function to use geolcoation values.
window.lat=1;
window.lon=3;
var SK= 1
if(SK==1)
{
navigator.geolocation.getCurrentPosition(showPosition);
}
//anything written here will be executed before even the getCurrentPosition retuns or sets the results
function showPosition(position)
{
alert("Latitude: " + position.coords.latitude + "-Longitude: " + position.coords.longitude);
//write your code here to use the location
}
here is the jsfiddle http://jsfiddle.net/Xa64Q/ explaining the issue if we are running alert after few seconds it returns correct value

Step through it with a debugger (like Chrome dev tools or Firebug for Firefox). This code works and is the same in principle. It works just fine for this sort of variable assignment:
window.x = 1;
function change() {
window.x = 2;
}
change();
alert(window.x);
My guess is that the getCurrentPosition call is abruptly failing. BTW, that call takes an error call back handler so you should define one for your code.

Related

Altering external variable from Google Maps' StreetViewService.getPanorama({},callback) method

I am running into trouble with this piece of code since I'm not sure how to fix it. I already asked this in the chats but couldn't figure out myself after some answers.
I want to get Panorama from StreetViewService using the method from the Google Maps javascript API from a StreetViewService getPanorama() method.
The method receives a literal with the coordinates and a radius, and a callback function that receives 2 parameters: data and status.
in that callback you check wether the service returns some images for street view or not, in which case you do one thing or another.
It seems the callback is executed asynchronously or the getPanorama method, executing some kind of ajax behind the scenes.
I'm pasting the code below, but first I explain my intentions. I need to return from one method I made inside a literal that is inside a self made library wether the the request has valid images for that requested coordinates or not by setting a variable to true or false and then at the end returning that value. However, even if I set the variable to true inside that callback anonymous function, when the variable returns, it always has it's initial value without it not being changed.
Here the code. Not everything, just the essential code.
Then my intention is to used the boolean returned to know if I have to switch one button active for some kind of job or not or do some things or not depending of if it returned true or false, Change some style etc as well.
I'd appreciate if you could change my code in a way it could be done. I was told about a callback solution or wrapping it into a promise. However I don't know how to do it. I used promisses in jquery but not in vanilla javascript. I'd like to see how the callback solution could be made as well with this code.
//Library not show for shortenning the example.
streetView: { //This is inside a library
valid_request: false,
event_key: null,
panorama: null,
setStreetView: function(coords, element) {
libMapa.streetView.valid_request = false; // Initialize the value again.
let sv_service = new google.maps.StreetViewService();
var latlng = coords;
sv_service.getPanorama({ // This is a method from Google Map Javascript API.
location: latlng,
radius: 50
}, function(data, status) {
if (status === google.maps.StreetViewStatus.OK) {
if (!libMapa.streetView.panorama) {
libMapa.streetView.panorama = new google.maps.StreetViewPanorama(element);
libMapa.streetView.panorama.setEnableCloseButton(true);
}
libMapa.streetView.panorama.setPano(null);
libMapa.streetView.panorama.setPano(data.location.pano);
libMapa.streetView.panorama.setVisible(true);
libMapa.streetView.valid_request = true;
} else {
alert("No images for this place");
// Otherwise variable stays as FALSE.
}
});
return libMapa.streetView.valid_request;
}
}
/****************************************/
//OUTSIDE THE LIBRARY IN INDEX.HTML
var sv_valid = libMapa.streetView.setStreetView(coords, div_mapa);
//sv_valid still shows false even if it should return true.
if (sv_valid) {
// "pressed" is to control a button as if it was a switch by activatinc and deactivating it.
pressed = false; // It always ends up being false even when it should return true.
element.style.cursor = "default";
libMapa.mapa.unByKey(libMapa.streetView.event_key);
}
Use a callback to do some action or modify some variable after the AJAX call to getPanorama() (and by proxy, setStreetView()) is complete.
Modify setStreetView() to accept a callback parameter and pass it along to getPanorama().
streetView {
// streetView variables etc.
setStreetView: function(coords, element, callback) {
// get ready for the AJAX call etc.
sv_service.getPanorama({
// parameter object
}, function(data, status){
// The getPanorama() callback.
// Do stuff with the data/status here,
// then call the callback function that you passed in to setStreetView.
// You can send data along (e.g. the result of the AJAX call) to the callback.
callback(someResult);
});
}
}
// somewhere else, where you're calling streetView.setStreetView()
var someVar = "foo";
streetView.setStreetView(someCoords, someElement, function(eventualResult){
someVar = eventualResult;
});
Here's a small example: https://jsfiddle.net/_jered/pgftxgf3/
I also highly suggest you do some research on AJAX, asynchronous JavaScript, and callbacks.

JavaScript callback firing out of sequence

I thought I'd finally figured out JavaScript callbacks as I found a use for one, but it is firing out of sequence.
In a Google Maps application I have a function which checks if the map is zoomed to the maximum level before allowing the user to store the (new) location of a marker.
The check function is:
function checkForMaxAccuracy(nextOperation) {
// Check at full zoom and alert if not
maxZoomService.getMaxZoomAtLatLng( newLocationMarker.getPosition(), function(response) {
var levelToZoomTo;
if (response.status != google.maps.MaxZoomStatus.OK) {
alert("Please ensure you are at maximum zoom to ensure most accurate placement possible.");
// continue after this alert as Mao could be fully zoomed but zoom service not reporting correctly
} else {
//alert("The maximum zoom at this location is: " + response.zoom);
if (response.zoom > map.getZoom()) {
alert("You must be zoomed in to the maximum to ensure most accurate placement possible before saving.\n\n Click [ Zoom here ] in theInfo Window to zoom to the maximum.");
// return after this error as Mao is definitely not fully zoomed
return;
}
// Call the update function to do the saving to the database
nextOperation();
}
});
}
Where nextOperation is the callback function.
This is called by two different functions, the first, and simplest (because it's not fully written yet) works perfectly:
function saveNewLocation() {
checkForMaxAccuracy(function () {
alert("save new");
});
}
If not fully zoomed I get the warning message displayed by the check function. If the map IS fully zoomed I get the alert 'save new' message displayed which is a place holder for the code to do the database update.
However, the same check function is also called from a more complete function. This other function is called when the user is updating the location of an existing marker.
This second function actually sets the onclick property of an HTML span object - effectively enabling and disabling the save control depending on what is going on.
In this function I am setting the onclick as follows:
document.getElementById('savePosition'+locationId).onclick = (state)?function(){checkForMaxAccuracy(doUpdate(locationId,"position"));}:null;
In this case, when I click the corresponding span element the doUpdate() function gets fired before the checkForMaxAccuracy() function.
(Apologies for the use of ternary operator.. I know if makes things a little difficult to read, but I'm leaving as is in my code in case I've got the bracketing or syntax slightly wrong here and that's what's causing my problems.)
My guess is I'm getting something fundamentally wrong in my 'understanding' of callback functions.
Can anyone explain what I'm doing wrong?
-FM
checkForMaxAccuracy(
doUpdate(locationId,"position")
);
will pass the returned value of doUpdate as an argument of checkForMaxAccuracy. In other words, you're not passing the callback function itself but its return value.
What you could do is:
checkForMaxAccuracy(
function() {
doUpdate(locationId,"position")
}
);

Chrome extension global variable weirdness

I have the following code in the popup.js of a chrome extension.
var tt;
chrome.tabs.query({ active: true, currentWindow: true, windowType: 'normal' },
function (tabs) {
tt = 5;
});
document.getElementById('elm').textContent = tt;
But the weird thing is value of tt is undefined when accessed out side of the function, but it shows "5" if the document.getElementById('elm').textContent = tt; is put inside the function. So why is the variable value is not retained when the control exit the function ?
What am I doing wrong here ?
This code runs when the popup is shown. I.e. when the browser action's button is clicked and I simplified the code be readable. Actually I'm trying to get the current tab's id in to a variable. But nothing works.
Just found the answer, if anyone ran into this again, this is what happened.
The chrome.tabs.query is an async operation so the callback function was called a little bit later. But the document.getElementById('elm').textContent = tt; line was executed before the callback was called and it caused the issue. When debugging this did not happen as the stepping through the code delays the execution of that line.

Set data inside getCurrentPosition function

I'm doing next:
First thing - I'm checking if I already have loaded latitude and longitude data. If I do have, I'm saving that into array named "location".
Second thing - if I don't have any loaded data, I'm trying to get current position. After that, I'm trying to save latitude and longitude for current position.
And, at the end, I'm calling setMap(); function where I check location array and where I'm generating a map.
Problem:
Well, as I said it...inside "getCurrentPosition", I'm trying to set current position into "location" array, and after that I'm trying to take those values inside setMap(); function. Here's the problem, but only when i set "location" values inside "getCurrentPosition". If I set "location" values manually before (from "data" array), everything works fine.
Also, when I call a setMap() function inside "getCurrentPosition", everything works fine...but when I call it from outside, won't work.
Can someone explain me what's going on and what can I do?
Here's my code:
location = new Array();
if (data.lat) {
location['lat'] = data.lat;
location['lng'] = data.lng;
} else {
if (!navigator.geolocation) {
//
} else {
navigator.geolocation.getCurrentPosition(function(position) {
location['lat'] = position.coords.latitude;
location['lng'] = position.coords.longitude;
});
}
}
setMap();
Thank you.
You are setting a different variable inside of getCurrentPosition.
I would suggest researching variable scope.
Check out this question.
--edit--
I did not realize that the function you were using was a part of Javascript, I thought you had written/gotten it from somewhere.
Also, I stand corrected about the scope. Since you are using an array, the scope is fine, you should be able to set it inside the callback function just fine.
I ran your code and got some strange printouts when I did a console.log on location.
I took a guess, and it appears that location is a reserved word. I bet that if you change the name of location to something else, your code should work fine.
--edit--
I should have realized this sooner actually, since location is the same as window.location, which is the browser bar location!

javascript setTimeout function out of scope

I am trying to call showUpload(); from within two setTimeouts. Neither works. It seems to be out of scope and I'm not sure why. I tried this.showUpload() which didn't work either.
$(document).ready(function(){
var progress_key = $('#progress_key').val();
// this sets up the progress bar
$('#uploadform').submit(function() {
setTimeout("showUpload()",1500);
$("#progressbar").progressbar({ value:0}).fadeIn();
});
// uses ajax to poll the uploadprogress.php page with the id
// deserializes the json string, and computes the percentage (integer)
// update the jQuery progress bar
// sets a timer for the next poll in 750ms
function showUpload() {
$.get("/myid/videos/uploadprogress/" + progress_key, function(data) {
if (!data)
return;
var response;
eval ("response = " + data);
if (!response)
return;
var percentage = Math.floor(100 * parseInt(response['bytes_uploaded']) / parseInt(response['bytes_total']));
$("#progressbar").progressbar({ value:percentage})
});
setTimeout("showUpload()", 750);
}
});
Thank you for your time.
As #Daniel said, this should work:
setTimeout(showUpload, 750);
Please note that the quotes should be removed (this is why it isn't being executed until the timeout runs out). Right now, you are passing a string, which is evaled when the timeout runs out. This eval will happen in a different scope, which is why you are seeing the problem you are seeing.
Instead, passing a reference to the showUpload function to setTimeout will allow your function to be executed later. Keep in mind that when it runs, it will be in a different scope, so you may have other scope issues, like with progress_key. You will need to create a closure around showUpload to capture that parameter.
It looks like you need to remove the parenthesis from showUpload in both your setTimeout calls. Otherwise you will be invoking the showUpload method instead of passing it as a parameter:
setTimeout(showUpload, 750);

Categories

Resources