How to get variable value outside angular function [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have been hours trying to understand why I don't get the value of a variable, outside an Angular.js function. First I get the value from a Firebase database, here is my reference :
var refspaedtServ = new Firebase(FBURLSPA + $routeParams.id);
$scope.spaedServ = $firebaseObject(refspaedtServ);
Then I have the function:
///// IMAGE REFERENCE ////
var lafoto = '';
refspaedtServ.on("value", function(rootSnapshot) {
lafoto = rootSnapshot.val().foto;
console.log("Inside image ", lafoto)
});
As you can see, I define my variable 'lafoto' as global
With the console.log Inside image, I can see the value is correct
But when I try to get the value of "lafoto" variable, outside the function, I'm getting "undefined", I mean no value.
console.log("Outside Image ", lafoto)
It seems silly, but I'm reaching madness for that.
Can anybody give me a hint please?
Regards,
Victor

It's pretty simple, let's see it by your code, assuming your function in the 'value' event needs 1500ms to complete:
var lafoto = '';
console.log('start');
//listening for the event
refspaedtServ.on("value", function(rootSnapshot) {
//after ~1500ms...
lafoto = rootSnapshot.val().foto;
console.log("Inside", lafoto)
});
console.log('outside', lafoto); //executed immediately
In console, you will receive as result:
'Start'
'outside'
'inside'
that's because you are waiting asynchronously for the event: hence, "outside" the .on function you are executing the code before the code inside.
So, your variable lafoto will always result undefined, because it has not been already assigned.
.
Edit 1
You can use a callback function to perform code after the .on event:
var lafoto = '';
console.log('start');
//listening for the event
refspaedtServ.on("value", function(rootSnapshot) {
//after ~1500ms...
lafoto = rootSnapshot.val().foto;
console.log("Inside", lafoto)
myAfterFunction();
});
function myAfterFunction(){
console.log('myAfterFunction', lafoto);
}
console.log('outside', lafoto); //executed immediately
In console, you will receive as result:
'Start'
'outside'
'inside'
'myAfterFunction'

Related

Reading Array of Json [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 2 years ago.
I have created a function that tries to get lat long based on the address and after that, I want those to print on console
How to get values of coords.... am I doing it in the correct way? please help to understand it.
coords = getLocationCoords("Ambala,Haryana,India,134003");
console.log(coords)
function getLocationCoords(fa){
var coords = [];
$.get(location.protocol + '//nominatim.openstreetmap.org/search?format=json&q='+fa, function(data){
coords['lat'] = JSON.parse(data[0].lat);
coords['lon'] = JSON.parse(data[0].lon);
});
return coords;
}//getLocationCoords
You cannot get the coords as "returned value", because there is nothing to return. That is, nothing to return until some handler is invoked, which could be 0.2 seconds later, or 3 seconds later. But if the handler returns it, you still won't be getting it since the assignment happened immediately. To solve this, you can also just make it a "promise", so that when the value is ready, you can then() it, and process the value, like follows:
getLocationCoords("Ambala,Haryana,India,134003")
.then(data => {
coords = data.map(loc =>
({
lat: Number(loc.lat),
lon: Number(loc.lon)
})
);
console.log("GOT IT", coords);
});
function getLocationCoords(fa) {
return $.get(location.protocol + '//nominatim.openstreetmap.org/search?format=json&q=' + fa)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Execution order of JavaScript [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I can't understand the execution order of the following. This part of a larger script, but the $( "#select-overlay" ) starts this going.
function findSelectedMap(mapID) {
$.getJSON('maps.json', function (json) {
json.forEach(function (entry) {
if (entry.maps.id == mapID) {
changeLayerTo = entry.maps.url;
maxZoom = entry.maps.zoom;
} // end if
}); // end json.forEach
}); // end $.getJSON
} // end findSelectedMap
function overlaySelector() {
$("#select-overlay").change(function () {
mapID = $("#select-overlay input[type='radio']:checked").val();
findSelectedMap(mapID); // using mapID, find the url, zoom for overlayMap selected
currentLayer = L.tileLayer(changeLayerTo).addTo(map);
// more map stuff
}); // end $( "#select-overlay" ).
} // end overlaySelector function
overlaySelector is called when the page loads in a Rails app
<script>
$(document).on("turbolinks:load", function()
{
overlaySelector();
});
</script>
I think changeLayerTo should be set on line 5 before currentLayer = L.tileLayer(changeLayerTo).addTo(map); is executed. The findSelectedMap(mapID) function is entered (I have a bunch of console.logs to track), and then execution jumps to the currentLayer = L.tileLayer(changeLayerTo).addTo(map); line (and errors, but I manually defined changeLayerTo just above so execution could continue, and then the json.forEach(function(entry) line executes and iterates over the dozen entries in maps.json and finds the correct value. But of course I need that value sooner.
What am I missing? Originally the findSelectedMap(mapID) was embedded in the overlaySelector function but I pulled it out to see if it would help, and it seemed like cleaner coding. All the variables are declared outside the functions. I don't imagine I'm approaching the problem in the best way, but I need the url and zoom (and eventually some other data related to the map).
Try the following:
function findSelectedMap(mapID, cb) {
$.getJSON('maps.json', function (json) {
json.forEach(function (entry) {
if (entry.maps.id == mapID) {
changeLayerTo = entry.maps.url;
maxZoom = entry.maps.zoom;
} // end if
}); // end json.forEach
cb();
}); // end $.getJSON
} // end findSelectedMap
function overlaySelector() {
$("#select-overlay").change(function () {
mapID = $("#select-overlay input[type='radio']:checked").val();
findSelectedMap(mapID, function() {
currentLayer = L.tileLayer(changeLayerTo).addTo(map);
}); // using mapID, find the url, zoom for overlayMap selected
// more map stuff
}); // end $( "#select-overlay" ).
} // end overlaySelector function
Basically, the cb param is a callback function that will be executed just after forEach loop ends and then this line currentLayer = L.tileLayer(changeLayerTo).addTo(map); will use the correct changeLayerTo.
UPDATE - As #Adriani6 suggests: You should pass the variables back via the callback rather than assigning them globally to the window object, of course, if they don't need to be global

Javascript: attempting to access variable outside of function getting 'undefined'

I am trying to access the time_pressed variable outside of function held() by returning time_pressed and doing console.log(held()) outside of the function. It is console.log-ing undefined. Why is it not working and how can I do what I need to do to access said variable outside of the function?
Here is my code..
function held(){
var time_pressed;
document.onmousedown = function(e){
mousedown_time = getTime();
console.log(mousedown_time);
}
document.onmouseup = function(e){
time_pressed = getTime() - mousedown_time;
console.log('You held your mouse down for', time_pressed,'miliseconds.');
}
return time_pressed
}
console.log(held())
Consider the following function:
function held(){
var time_pressed;
return time_pressed;
}
console.log(held());
What do you expect the function to return? No value has been defined, so the value is undefined.
The only thing(s) you're doing in that function is assigning event handler functions to the document. Which means two things:
Those are separate functions and what they return isn't what this returns.
Those functions won't be executed until some later time when that even occurs.
You're successfully creating those event handlers. So it's not clear why you're trying to log some returned value. The function you're executing doesn't return anything, nor does it need to. There's nothing to be logged. Your event handlers will log to the console when they execute.
So, held() just sets up the handlers in your code. Your time_pressed variable holds nothing until the handlers fire to populate it. Give this a try:
function held(){
var time_pressed;
var mousedown_time;
document.onmousedown = function(e){
mousedown_time = getTime();
console.log(mousedown_time);
}
document.onmouseup = function(e){
time_pressed = getTime() - mousedown_time;
console.log('You held your mouse down for', time_pressed,'miliseconds.');
}
}
held();
edit: for the sake of completeness, getTime() needs to be defined. I went with:
function getTime(){ return new Date().getTime(); }

Access this in prototype function after a callback [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 7 years ago.
I have following code :
function A() {
this.value = 'a_value';
}
A.prototype.getValue = function(){
console.log(this.value); // got undefined, expected 'a_value'
}
setTimeout(new A().getValue, 100);
why i get this.value as undefined.?
and how how do i access this.value?
EDIT : i am not allowed to change the setTimeout line (last line) of code.
Hint: have you tried console.log(this);?
You are only passing the getValue function to setTimeout, not its context. Something like this would work: setTimeout(function() {new A().getValue();},100); But without changing that last line, there's basically nothing you can do.
you can avoid using the this altogether and not having this kind of problems with the following technique :
var A = function () { // no new no this
var value = 'a_value';
var getValue = function(){
console.log(value);
};
return Object.freeze({
getValue ,
});
};
setTimeout(A().getValue, 100);
or write
var a = new A();
before, and then
setTimeout(a.getValue.bind(a), 100);

js function inside function and wait for return value [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
How to return AJAX response Text? [duplicate]
(2 answers)
Closed 9 years ago.
$(document).ready(function(){
// Global function (will be include in any HTML file)
function m3_result(size_1, size_2, size_3){
$.get('http://www.google.com', function(data){
return data;
});
}
// Another function
function calculate(){
var size_1 = parseFloat($('#add_document_form #size_1').val());
var size_2 = parseFloat($('#add_document_form #size_2').val());
var size_3 = parseFloat($('#add_document_form #size_3').val());
var ax = m3_result(size_1, size_2, size_3);
alert(ax); // Here ax return: UNDEFINED
}
// Run
calculate();
});
Results are "undefined", but I would like that calculate() will wait for m3_result() to execute. I see that here problem is coming when I added $.get(), but its needed...
I have searching for callback() like functions, but none fit to my needs, or I just didnt put that right.
Any help will be highly appreciated, thanks.
GET url will be localy and element IDs are also ok.
You can't return a result from an asynchronous function, instead you can return a promise to supply that value later, which as it happens is the jqXHR object returned by $.get:
function m3_result() {
return $.get(...)
}
and do the same in calculate:
function calculate() {
...
return m3_result(...);
}
and then wait for the result, which will be passed as a parameter to the callback registered with the .done function:
calculate().done(function(result) {
alert(result);
});

Categories