1

Long story short, im newish to NodeJS and im trying to change a variable after a function has been executed, however I cant return a result like I thought I could.

app.get('/:steamid', function(req, res) {

    var steamID;
    var steamAvatarUrl;
    var steamRegisterDate;

    steamAPI.ResolveVanityURL(req.params.steamid, function(err, res) {
        console.log('Steam64: ' + res); // <- this prints out my result
        steamID = res;
    });

    steamAPI.getAvatarUrl(req.params.steamid, function(err, res) {
        console.log('Avatar URL: ' + res); // <- this prints out my result
        steamAvatarUrl = res;
    });

    steamAPI.memberSince(req.params.steamid, function(err, res) {
        console.log('Registered: ' + res); // <- this prints out my result
        steamRegisterDate = res;
    });

    console.log(steamID); //<--- This returns undefined

    res.render('steamid.hbs', {
        "title": steamID,
        "avatarURL": steamAvatarUrl,
        "registerDate": steamRegisterDate
    });
});

An help with an example/resolution of how I accomplish this would be amazing. I am a visual learner so please dont say "use this or do that" without giving some sort of example to it or I honestly wont get it lol.

Thanks ahead of time.

Zendrex
  • 11
  • 1
  • 3

5 Answers5

1

Javascript is Async in nature, so before it fetches the data you are trying to print it. You can write console.log() inside your callback function. or please use promises.

Rinkesh Golwala
  • 979
  • 1
  • 7
  • 17
1

You can solve this problem using Promise. Your api call is async. So it will not wait to complete the api call. it just executes console.log(). That's why you are getting undefined. I'm not sure about your node version. if promises are not available you could use bluebird library.

app.get('/:steamid', function(req, res) {

   var steamID;

   new Promise(function(resolve, reject){
    steamAPI.ResolveVanityURL(req.params.steamid, function(err, res) {
       resolve(res);
    });
  }).then(function(res){
      steamID = res;
      console.log('Steam64: ' + steamId);
    }
});
Dinesh undefined
  • 5,490
  • 2
  • 19
  • 40
1

Javascript is asynchronous by default. You can't return a value inside of a callback function neither can you assign to a variable outside as it is returned immediately.

app.get('/:steamid', function(req, res) {

    steamAPI.ResolveVanityURL(req.params.steamid, function(err, res) {
        console.log('Steam64: ' + res); // <- this prints out my result
        var steamID = res;
        console.log(steamID); // <-- defined
    });
});

You could learn about Promises and how they work as they are preferred to using callbacks.

codejockie
  • 9,020
  • 4
  • 40
  • 46
0

@Zenderx let breif this .

Node.js is Async programming , if you do any I/O event like database call ,http , timeout call . It send then in event pool and execute in sequence .

See the comment what happens step by step. What is happing in your code it this.

This is your api call

  app.get('/:steamid', function(req, res) {

    // excution comes inside 
    var steamID;
     // then you call an I/O event and iniallized streamID but what happen here is this , 
    //this is I/O event so went to event loop for excution
    steamAPI.ResolveVanityURL(req.params.steamid, function(err, res) {
        console.log('Steam64: ' + res); // <- this prints out my result
        steamID = res;
    });
    // while the block is in event loop or excution this statement run because of Async nature

    console.log(steamID); //<--- This returns undefined

    (...)
});

if you want to print StreamID print it inside the block only .

 steamAPI.ResolveVanityURL(req.params.steamid, function(err, res) {
            console.log('Steam64: ' + res); // <- this prints out my result
            steamID = res;
        console.log(steamID);
        });

Too study in depth of async , you can look to promise and async library in node.js .

The simplest thing to do for newbie is this .

app.get('/:steamid', function(req, res) {

    var steamID;
    var steamAvatarUrl;
    var steamRegisterDate;

    steamAPI.ResolveVanityURL(req.params.steamid, function(err, resu) {
        console.log('Steam64: ' + resu); // <- this prints out my result
        steamID = resu;
       steamAPI.getAvatarUrl(req.params.steamid, function(err, resu) {
          console.log('Avatar URL: ' + resu); // <- this prints out my result
          steamAvatarUrl = resu;
         steamAPI.registerDate(req.params.steamid, function(err, resu) {
            console.log('Registered: ' + resu); // <- this prints out my result
             steamRegisterDate = resu;
                console.log(steamID); //<--- This returns undefined

            res.render('steamid.hbs', {
           "title": steamID,
           "avatarURL": steamAvatarUrl,
           "registerDate": steamRegisterDate
              });
          });
        });
    });

});

If you need it to be solve by promise and async module ping.

Himanshu sharma
  • 7,487
  • 4
  • 42
  • 75
0

Javascript is asynchronous in nature. The function 'steamAPI.ResolveVanityURL()' is taking time to execute and therefore next statement 'console.log(steamID)' is getting executed before waiting for the result.

You can either use callbacks or below is an example using 'q' promise library to solve your problem -

var Q = require('q');

app.get('/:steamid', function(req, res) {
    var steamID;
    resolveUrl(req.params.steamid).then(function(steamID) {
        console.log(steamID); //<--- This will return steamID
        (...)
    });
});

function resolveUrl(id) {
    var deferred = Q.defer();
    steamAPI.ResolveVanityURL(id, function(err, res) {
        console.log('Steam64: ' + res); // <- this prints out my result
        deferred.resolve(res);
    });
    return deferred.promise;
}

Also here is a link to get more information about promises in node.js - http://www.dotnetcurry.com/nodejs/1242/promises-nodejs-using-q-goodbye-callbacks

Hope this solves your problem.