Home NodeJS Change variable from within a function
Reply: 5

NodeJS Change variable from within a function

Zendrex
1#
Zendrex Published in 2017-11-14 06:05:07Z

This question already has an answer here:

  • Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference 6 answers
  • How to return the response from an asynchronous call? 24 answers

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.

Rinkesh Golwala
2#
Rinkesh Golwala Reply to 2017-11-14 06:07:28Z

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.

Himanshu sharma
3#
Himanshu sharma Reply to 2017-11-14 06:58:19Z

@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.

Paras Wadhwa
4#
Paras Wadhwa Reply to 2017-11-14 06:40:36Z

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.

Dinesh
5#
Dinesh Reply to 2017-11-14 06:37:32Z

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);
    }
});
John Kennedy
6#
John Kennedy Reply to 2017-11-14 06:43:40Z

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.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.267557 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO