splunk splunk - 2 months ago 32
TypeScript Question

Wait until async call has finished - Ionic2

I'm working in Ionic2 and I have this problem:
In my component there is

drawPlayer
method which retrieves data from firebase database.

Here is its code:

drawPlayer(){
this.playerData.drawThePlayer().on('value', snapshot => {
// some stuff
});
return this.drawnPlayer; // returns the player name
}


In the same file (component) inside
ngOnInit
function I need to call
drawPlayer()
and I do:

ngOnInit(){
let myVar = this.drawPlayer();
console.log("test: "+myVar);
}


If I inspect the console I read
test: undefined
, if I go back and return to that page again, I see
test: a correct value
. I think this is because of that
drawPlayer()
is an asyncronous call and when I do
console.log
it hasn't returned the result yet.

So, how can I
console.log
only after
drawPlayer()
has finished?

/*****************************************************************************/

EDIT: (after httpNick answer)

Now I have this
drawPlayer()
method with complete code (this.drawnPlayer is defined out of these methods, globally):

drawPlayer(cb){
this.playerData.drawThePlayer().on('value', snapshot => {
var data = snapshot.val();
for (var key in data){
this.drawnPlayer = String(data[key].lastName);
console.log("playerName: "+this.drawnPlayer);
}
});
console.log("test: "+this.drawnPlayer);
cb(this.drawnPlayer); // returns the player name
}


ngOnInit() is like this:

this.drawPlayer(function(valueFromDrawPlayer) {
console.log("callback result: "+valueFromDrawPlayer);
});
console.log("after the callback");


When I run the app this is what I see in browser console:

test: undefined
callback result: undefined
after the callback
EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property '0' of undefined
playerName: John


But I expect to read this:

playerName: John
test: John
callback result: John
after the callback

Answer

I am not sure where this.drawnPlayer comes from, but if you pass in a callback function to drawPlayer you can call that after the async code has finished running to be able to log the return value.

drawPlayer(cb){
    this.playerData.drawThePlayer().on('value', snapshot => {
      // some stuff
    });
    cb(this.drawnPlayer);   // returns the player name
}
ngOnInit(){
    drawPlayer((x) => { console.log(x) });
}

Last line can be rewritten to this as well:

drawPlayer(function(valueFromDrawPlayer) {
    console.log(valueFromDrawPlayer);
});

EDIT AFTER SEEING FULL CODE:

drawPlayer(cb){
    this.playerData.drawThePlayer().on('value', snapshot => {
      var data = snapshot.val();
      for (var key in data){
            this.drawnPlayer = String(data[key].lastName);
            console.log("playerName: "+this.drawnPlayer);
            cb(this.drawnPlayer);   // returns the player name
      }
    });
}