0

I'm using NodeJS request to get some JSON from a url and then using the JSON object to get data. But I don't know how to use the data, e.g. put it in a variable without getting not defined error because it doesnt wait for the json response to come through. I saw this: https://www.twilio.com/blog/2015/10/asyncawait-the-hero-javascript-deserved.html

But I wont be able to use ES17 features / dont want to do that.

Example 1: Basic Request

var request = require('request');

var url = 'https://api.github.com/users/rsp';

request.get({
    url: url,
    json: true,
    headers: {'User-Agent': 'request'}
  }, (err, res, data) => {
    if (err) {
      console.log('Error:', err);
    } else if (res.statusCode !== 200) {
      console.log('Status:', res.statusCode);
    } else {

      var jsonObj = data.html_url
    }
});

console.log(jsonObj) // error not defined

# Example 2: Request promise
require("request/package.json"); // request is a peer dependency. 
var rp = require("request-promise")

var options = {
uri: 'http://api.open-notify.org/astros.json',
headers: {
    'User-Agent': 'Request-Promise'
},
json: true 
};

rp(options)
.then(function (jsonTest) {
    var jsonObj = jsonTest.number;
    console.log(jsonObj)
})
.catch(function (err) {
    // API call failed...
    console.log("failure")
});

So how do I change either of the above examples so you could use the json data outside the request and in later code?

Edit:

I now see that callbacks, promises, async / await are all asynchronous and all either rely on writing code nested in them or code like await that waits for it to return then executes code.

I can see why Promises and async / await are keenly awaited, even if callbacks can do anything, asynchronous code can just get really ugly and unreadable. Thats why I thought it was wrong to nest everything that relies on the callback, but its fine.

o0o0o0o0o
  • 89
  • 1
  • 11
  • 1
    You cannot do it outside. Anything you want to do after the request being processed you have to do it inside the callback function or in the then block. This is the basic principal of asynchronous programming. – Mustafa Mamun Nov 23 '17 at 09:33

2 Answers2

1

For your callback example, anything that needs results from the request has to be run within the callback. See below.

request.get({
    url: url,
    json: true,
    headers: {'User-Agent': 'request'}
  }, (err, res, data) => {
    if (err) {
      console.log('Error:', err);
    } else if (res.statusCode !== 200) {
      console.log('Status:', res.statusCode);
    } else {

      var jsonObj = data.html_url
      console.log(jsonObj) // error not defined //You must use the variable here. 
    }
});

The reason is that anything outside that callback will be executed before the callback. In your particular case, the callback will actually only be executed after console.log(jsonObj)

Sello Mkantjwa
  • 1,798
  • 1
  • 20
  • 36
  • Yes I know. Thats my problem. Since I know async can solve code executing before the response (see my edit), I know that promises / callbacks can do it. If no one gives me an actual answer I'll be forced to make a really shitty if condition that depends on a variable which changes when the callback works. – o0o0o0o0o Nov 23 '17 at 09:55
  • Also i didnt know what a callback was until today, but im starting to think that I could 'solve' this by adding another callback, and enter callback hell. Promises should be better but I dont know how to use them... – o0o0o0o0o Nov 23 '17 at 09:59
  • Im not sure I understand. Why would you need another callback? You only you can do all you need to do in your one current callback. – Sello Mkantjwa Nov 23 '17 at 10:10
  • Yes I wouldnt really do another callback. Ive now realised that since the callback / promise always executes last, nothing executes after it. So callbacks seem really shit now if once you use it, if all your code depends on the result of the callback, ALL the code has to be in the callback. This seems extremely weird to me. I could have 1000 lines of code, functions, orm queries, stuff totally unrelated to the callback but forced inside it anyway because the code execution depends on what the callback is returning. See my confusion? – o0o0o0o0o Nov 23 '17 at 10:16
  • Ok my realisations: 1. Promises and callbacks both are for asynchronous code, promises are just sometimes better. 2. I have to either wait for the callback / response to end, or put all code nested in callback – o0o0o0o0o Nov 23 '17 at 10:24
  • It becomes natural once you get used to it. Also, not all of your code will necessarily be in the callback. If there is something that does not depend on the result in the callback, then that code can be executed without having to wait for the result. That is really the whole point. If you want your code to look cleaner, you can of course minimize the use of anonymous inline functions. As in [this gist](https://gist.github.com/sellomkantjwa/d0c36d878c0e4c392141e9aa742eb4da) of your code, reforematted. – Sello Mkantjwa Nov 23 '17 at 10:25
  • Yes both callbacks and promises are use for handling code. Just depends on what you prefer, I personally prefer callbacks. – Sello Mkantjwa Nov 23 '17 at 10:27
  • Yes, ok. Sorry just the reason why I made this question was because im shocked this is how callbacks work, I thought they were like if statements or something. Also questions like: https://stackoverflow.com/questions/5010288/how-to-make-a-function-wait-until-a-callback-has-been-called-using-node-js seem to be asking for a way to wait for the callback to end then execute code outside it, but I dont understand that question / answer very well so I cant tell. – o0o0o0o0o Nov 23 '17 at 10:29
0

Here is a simple example of how to do this using request without ES6

var request = require('request');
request('http://api.open-notify.org/astros.json', function (error, response, body) {
      var body = JSON.parse(body)
      console.log(body.number);
});
NItin Vaja
  • 177
  • 1
  • 6