-1

could someone help me with this code? It is simplified to see the problem easier, which is the variable myGlobalVar does not behave like global.

var request = require('request');
var myGlobalVar = "myglobalstring";
var options = {
  url: 'https://api.github.com/repos/request/request',
  headers: {
    'User-Agent': 'request'
  }
};

function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    var info = JSON.parse(body);
    myGlobalVar = info.stargazers_count + " Stars";
    console.log(myGlobalVar + "-1");
  }
  //myGlobalVar = info.stargazers_count + " Stars";
  // console.log(myGlobalVar+"-2");
}
request(options, callback);
console.log(myGlobalVar + "-3")

The result of this is

myglobalstring-3

23038 Stars-1

23038 Stars-2 (Uncommenting those lines)

The variable does not keep the value outside the function...

adiga
  • 34,372
  • 9
  • 61
  • 83
  • This is happening because your code is asynchronous. Your `callback` function will be called _x time_ once the request is made (ie: `callback` will take some time to be called once you have invoked the `request` method). Your `console.log()` runs almost immediately after you make your request, and so it will run before your `callback` function runs. You either need to put your `console.log` in your callback, use `promise`s or `async/await` (all of these methods are described in the duplicate) – Nick Parsons Jul 27 '19 at 06:52
  • I see, thanks for you feedback. I will check on that. – Laurent Mikhail Jul 27 '19 at 15:30

2 Answers2

0

What you need to understand is that request is an asynchronous function call, it makes the REST API call behind the scenes and the response is received at a later time interval after which the callback function is executed. That's why when you call request the execution flow immediately goes to the next line without waiting for the response and shows myglobalstring-3.

To solve this you need to move console.log(myGlobalVar + "-3") to inside the callback function. Like this,

var request = require('request');
var myGlobalVar = "myglobalstring";
var options = {
  url: 'https://api.github.com/repos/request/request',
  headers: {
    'User-Agent': 'request'
  }
};

function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    var info = JSON.parse(body);
    myGlobalVar = info.stargazers_count + " Stars";
    console.log(myGlobalVar + "-1");
  }
  //myGlobalVar = info.stargazers_count + " Stars";
  // console.log(myGlobalVar+"-2");

    // Now it should print the value you expect
    myGlobalVar = info.stargazers_count + " Stars";
    console.log(myGlobalVar + "-3")
}
request(options, callback);

Another approach is to use promises and async/await. Use this axios, or if you prefer request then use request-promises, instead.

Here is an article that explains promises and async/await, https://stackabuse.com/node-js-async-await-in-es7/

Ramaraja
  • 2,526
  • 16
  • 21
0

myGlobalVar is behaving exactly like a global variable in your code. What you probably want is console statements to print in the order mentioned like -1,-2,-3. For this to happen, you will need to understand async functions in javascript. Refer https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Just to show that myGlobalVar indeed has the last value assigned to it after request is made, please see alteration made to your code below. We are calling setTimeout function to see what myGlobalVar contains after 5 seconds (assuming the request has already been made in that timeframe).

var request = require('request');
var myGlobalVar = "myglobalstring";
var options = { url: 'https://api.github.com/repos/request/request', headers: {'User-Agent': 'request'}};
function callback(error, response, body) 
{
if (!error && response.statusCode == 200) 
{
var info = JSON.parse(body);
myGlobalVar = info.stargazers_count + " Stars";
console.log(myGlobalVar+"-1");
}
myGlobalVar = info.stargazers_count + " Stars";
console.log(myGlobalVar+"-2");
}
request(options, callback);           
setTimeout(function(){
   console.log(myGlobalVar+"-3");
},5000);

This will give you output as below

"23038 Stars-1"
"23038 Stars-2"
"23038 Stars-3"

You can also check the same at https://runkit.com/5d3bf6ac32e3bb001467a45d/5d3bf6ad59cbcf0015d00af3

Shirish Goyal
  • 510
  • 2
  • 9
  • I look to use the body return outside the function. – Laurent Mikhail Jul 27 '19 at 15:30
  • You will have to ensure wherever you are fetching the value is actually called post request has been made and returned in that case. See how promises and async/await are used in javascript to understand it more. – Shirish Goyal Jul 28 '19 at 10:34