NodeJS return http.request - javascript

Hi now I know that NodeJS is asynchronous (which I am still trying to get my head around to be honest).
The problem that I am currently facing is I have attempting to do a http.request to receive some JSON data. This is fine but what I need is to return this data to a variable. I believe I need to do a callback function? (from what I have read up on the matter)
The Code that I currently have:
var http = require('http');
pCLatLng = '';
function postCodeCheck() {
var pCode = {
host: 'geo.jamiethompson.co.uk',
path: "/" + 'SW1A2AA' + ".json"
};
http.request(pCode).on('response', function(response) {
var data = '';
response.on("data", function (chunk) {
data += chunk;
});
response.on('end', function () {
pCJSON = JSON.parse(data);
pCLatLng = pCJSON;
});
}).end();
}
console.log(pCLatLng);
This is obviously outputting "undefined"; I have tried returning the response.on('end') when having return "hi" or anything inside it instead NodeJS outputs the information about the site. If anyone can help with this it would be much appreciated.

console.log(pCLatLng); needs to be inside (or inside something called by) the response.on('end' callback. The value isn't available until that callback is fired.
Try something like:
function postCodeCheck(callback) {
var pCode = {
host: 'geo.jamiethompson.co.uk',
path: "/" + 'SW1A2AA' + ".json"
};
http.request(pCode).on('response', function(response) {
var data = '';
response.on("data", function (chunk) {
data += chunk;
});
response.on('end', function () {
callback(JSON.parse(data));
});
}).end();
}
postCodeCheck(function (pCLatLng)
{
console.log(pCLatLng);
});

You want something like this:
var http = require('http');
function postCodeCheck(cb) {
var pCode = {
host: 'geo.jamiethompson.co.uk',
path: "/" + 'SW1A2AA' + ".json"
};
http.request(pCode).on('response', function(response) {
var data = '';
response.on("data", function (chunk) {
data += chunk;
});
response.on('end', function () {
var pCJSON = JSON.parse(data);
cb(pCJSON);
});
}).end();
}
postCodeCheck(function(pCLatLng) { console.log(pCLatLng); });
Look carefully for the differences before using.

You'll need your postCodeCheck() function to take a callback as well, just like http.request. In the world of async, calling callbacks with results takes a similar role to returning results.

Related

CallbackHandler in Node.js

I have the following method in a .js file for an asynchronous network connection
function requestWatsonDiscovery(queryString) {
console.log('Query =', queryString);
if (typeof queryString !== 'undefined') {
var discoveryUrl = `something`
console.log('Total url =', discoveryUrl);
var options = {
host: 'gateway.watsonplatform.net',
path: discoveryUrl,
auth: auth
};
http.get(options, function(http_res) {
// initialize the container for our data
var data = "";
// this event fires many times, each time collecting another piece of the response
http_res.on("data", function(chunk) {
// append this chunk to our growing `data` var
//console.log(data);
data += chunk;
});
// this event fires *one* time, after all the `data` events/chunks have been gathered
http_res.on("end", function() {
// you can use res.send instead of console.log to output via express
//console.log(data);
data = JSON.parse(data);
watsonReturnedText = parseData(data);
//console.log(watsonReturnedText);
//returnResult();
});
});
}
}
at the same time I am updating my UI in another .js file.I want to get notified when the above asynchronous method has completed. I understand I can use callbacks /promises to do it.Can you show me the syntax to write a promise or a call back.
Simply put, this should give you basic understanding of callback in your demo
function requestWatsonDiscovery (queryString, callback){ // <- new param
http.get(options, function (http_res) {
var data = "";
http_res.on("data", function (chunk) {
data += chunk;
});
http_res.on("end", function () {
var parseData =JSON.parse(data);
callback(parseData); // <- usage of new param
});
});
}
requestWatsonDiscovery(null, function(result) {
// result is your data;
console.log(result);
});
This is basically..
function requestWatsonDiscovery (queryString){
return new RSVP.promise((resolve, reject) => {
if (typeof queryString !== 'undefined') {
var discoveryUrl = `something`
var options = {
host: 'gateway.watsonplatform.net',
path: discoveryUrl,
auth : auth
};
http.get(options, function (http_res) {
var data = "";
http_res.on("data", function (chunk) {
data += chunk;
});
http_res.on("end", function () {
data =JSON.parse(data);
watsonReturnedText = parseData(data);
resolve(watsonReturnedText);
});
});
}
else { reject(); }
}); //end promise
}
When you call your requestWatsonDiscovery do this...
var watsonPromise = requestWatsonDiscovery(queryString);
watsonPromise.then((data) => {
//use your watson data
}).catch(() => {
//manage the error
});

How to access variables within closures in Javascript [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I am creating a weather app using Node.js to access the current weather.
When I call the openweatherapp API, the temperature variable retrieved through the JSON that I am trying to pass on to module.exports is nested within a series of closure functions.
Is there any way for me to access the temperature and pass it through module.exports so I can retrieve the data from another file?
var http = require('http')
const apiKey = "myAPIkey"
// Connect to API URL api.openweathermap.org/data/2.5/weather?q={city name}
function accessWeather(city, callback) {
var options = {
host: "api.openweathermap.org",
path: "/data/2.5/weather?q=" + city + "&appid=" + apiKey + "",
method: "GET"
}
var body = ""
var request = http.request(options, function(response) {
response.on('data', function(chunk) {
body += chunk.toString('utf8')
})
response.on('end', function() {
var json = JSON.parse(body)
var temperature = parseInt(json["main"]["temp"] - 273)
})
})
request.end()
}
temp = accessWeather("Calgary")
console.log(temp)
module.exports = {
accessWeather: accessWeather
}
Well here we have a misconception of how async works in JavaScript. You can't return data that are going to be loaded in the future.
There are few options to solve this.
1 ) Export a function that takes another function as a parameter and call that function when you resolve your data :
module.export = function accessWeather(city, callback) {
var options = {
host: "api.openweathermap.org",
path: "/data/2.5/weather?q=" + city + "&appid=" + apiKey + "",
method: "GET"
}
var body = ""
var request = http.request(options, function(response) {
response.on('data', function(chunk) {
body += chunk.toString('utf8')
})
response.on('end', function() {
var json = JSON.parse(body)
var temperature = parseInt(json["main"]["temp"] - 273);
callback(temperature);
})
})
request.end()
}
2 ) Because the callback style is legacy now, you can do something even better with Promises.
module.export = function accessWeather(city, callback) {
return new Promise(function(resolve, reject){
var options = {
host: "api.openweathermap.org",
path: "/data/2.5/weather?q=" + city + "&appid=" + apiKey + "",
method: "GET"
}
var body = ""
var request = http.request(options, function(response) {
response.on('data', function(chunk) {
body += chunk.toString('utf8')
})
response.on('end', function() {
var json = JSON.parse(body)
var temperature = parseInt(json["main"]["temp"] - 273);
resolve(temperature);
})
})
request.end()
});
}
You can use also ESNext features like Generators and what I prefer even more if using Observables.

Node.js access the value of variable from another function

How do i get the value of myObject.myname, myObject.myage from the function getval? It returns undefined when i console.log it. Btw I'm using node js. Thanks.
var post = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (data) {
console.log('Response: ' + data);
var myObject = JSON.parse(data);
console.log('----------------------------------------------');
console.log(myObject.myname);
console.log(myObject.myage);
console.log('----------------------------------------------');
});
});
function getVal() {
//some code here
console.log(myObject.myname);
console.log(myObject.myage);
}
Declare myObject outside the anonymous function you pass to request (var myObject) instead of inside it. At present it is a local variable.
Call getVal() after the HTTP response has been received (otherwise it won't have been set yet). At present you aren't calling it at all.
There is a scope issue, can you try this instead?
var myObject = {};
var post = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (data) {
console.log('Response: ' + data);
myObject = JSON.parse(data);
console.log('----------------------------------------------');
console.log(myObject.myname);
console.log(myObject.myage);
console.log('----------------------------------------------');
});
});
function getVal() {
//some code here
console.log(myObject.myname);
console.log(myObject.myage);
}

Variable in node.js JavaScript doesn't change

'use strict';
var http = require('http');
function simpleTest() {
var content = '';
http.get("http://google.com/", function (res) {
var html = '';
res.on('data', function (chunk) {
html += chunk;
});
res.on('end', function () {
content = html;
});
});
return content;
}
console.log(simpleTest());
Why variable doesn't change and I get an empty string?
I think that the first function displays variable, and only then execute the http.get. How to make the first code executed and only then the function returns a variable?
It's because the operation is asynchronous. This means that simpleTest returns long before the http.get() response arrives.
Any code that needs the response must be invoked from in the callback. In your case, there could be multiple invocations of the data callback, so you need to handle it inside the end callback.
'use strict';
var http = require('http');
function simpleTest() {
http.get("http://google.com/", function (res) {
var html = '';
res.on('data', function (chunk) {
html += chunk;
});
res.on('end', function () {
console.log(html);
});
});
}
simpleTest();
If you don't want to hardcode the console.log(), you can put it in a function, and pass the function to simpleTest(). This makes it much more generic.
'use strict';
var http = require('http');
function simpleTest(fn) {
http.get("http://google.com/", function (res) {
var html = '';
res.on('data', function (chunk) {
html += chunk;
});
res.on('end', function () {
fn(html);
});
});
}
simpleTest(function(data) {
console.log(data);
});
So here we passed a function to the fn parameter, and invoked the fn parameter inside the end callback.
When we invoke it, we pass the final html value, and the callback receives it in its data parameter.
These are very common patterns, so it would be a good idea to get familiar with them.

How to return values from functions making HTTP request in node.js?

The getStockValue() function is called from another javascript file in the following way:
var r=require("./stockfile");
var returedData = r.getStockValue());
here returnedData contains only "-START-".
My objective is to get the body object returned from the function, after receiving the response. I've tried putting a return statement into the 'close' event handler, but it didn't work.
How should I do that?
function getStockValue() {
var http = require('http');
var options = {
host: 'in.reuters.com',
path: '/finance/stocks/overview?symbol=RIBA.BO',
method: 'GET'
};
var body = "--START--";
var req = http.request(options, function (res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.on('data', function (chunk) {
body += chunk;
});
res.on('close', function () {
console.log("\n\nClose received!");
});
});
req.on('error', function (e) {
console.log('problem with request: ' + e.message);
});
req.end();
return body + '... recieved';
}
exports.getStockValue = getStockValue;
As this is an asynchronous operation if will return straight away and continue to run in the background, hense why you only receive -START-. You can resolve this with the help of a callback function. Heres how:
Call the function as follows:
r.getStockValue(function(result) {
var returedData = result
//... rest of your processing here
}));
and within the getStockValue function change to this:
function getStockValue(callback) {
...
res.on('data', function (chunk) {
body += chunk;
callback(body);
});
...
}

Categories

Resources