0

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

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
CaribeSoft
  • 577
  • 1
  • 8
  • 25
  • 3
    Looks like the classic async question. See if this helps http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – elclanrs Aug 14 '16 at 18:43
  • `"value"` event is asynchonous. Try to log `lafoto` variable outside of the function in timeout: `setTimeout(function(){ console.log(lafoto); }, 1000);` – Paweł Lula Aug 14 '16 at 19:06
  • Hi Pawel, thank for your hint, now I understood that I have to wait for the response, if I use the setTimeout as you metioned in your comment it works, "inside" the function, the console.log(lafoto) display the correct value, but if I try to use this value outside the setTimeout function, again I dont get the value, just undefined. Maybe I'm not do it right, the thing I want to do is get the data value of "foto" field on firebase collection, and set this value on the storage reference, like this: var starsRef = storageRef.child('fotos/'+ lafoto); – CaribeSoft Aug 15 '16 at 04:19

1 Answers1

2

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'
illeb
  • 2,942
  • 1
  • 21
  • 35
  • Thanks Luxor001, your right, I have to give it time to get response, I create another function : setTimeout(function(){ console.log(lafoto); }, 1000);, but again I'm stucked, when I try to get the value outside setTime function, I only get undefined. What do you think? – CaribeSoft Aug 15 '16 at 04:26
  • You can't resolve an async problem with another one: by calling a setTimeout function, you are waiting asynchronously for 1000 ms to execute the code inside the function (console.log(lafoto). So, you are receiving undefined because lafoto has not been assigned already (your setTimeout function is called BEFORE the .on("value")). What you need to do is to execute the code you need inside the .on("value" function), so you'll be sure lafoto is initialized. – illeb Aug 15 '16 at 08:15
  • Or, you can use a callback function. i'll add the code in my answer – illeb Aug 15 '16 at 08:16