HTTP request callback on Node JS - javascript

Hi I am trying to get a response via a http using the callback method. But I get an error saying callback is not a function.
module.exports.ipLookup = function (res, callback) {
var http = require('http');
var str = '';
var options = {
host: 'ip-api.com',
port: 80,
path: '/json/',
method: 'POST'
};
var str= "";
var req = http.request(options, function (res) {
res.on('data', function (body) {
str += body;
});
res.on('end', function () {
callback(str);
});
});
req.end();
return str;
}
What is should to id return the json api response via ip-api.com. If anyone can help me on this it would be greatly appreciated.

In the other file you are loading the function from you need to ensure the callback parameter is used. See snippet below
var Lookup = require('./ip');
Lookup.ipLookup(function (response) {
console.log(response) // check if response is valid
})
You need to change the exported function to only accept one parameter as the first parameter is not used inside function body like so.
module.exports.ipLookup = function (callback) {
var http = require('http');
var str = '';
var options = {
host: 'ip-api.com',
port: 80,
path: '/json/',
method: 'POST'
};
var req = http.request(options, function (res) {
res.on('data', function (body) {
str += body;
});
res.on('end', function () {
return callback(str);
});
});
req.end();
}

Related

My weather app is throwing type error of temp.. It was console logging the data when I checked but as I enter city Lat and Log it shows type error [duplicate]

I'm trying to get my function to return the http get request, however, whatever I do it seems to get lost in the ?scope?. I'm quit new to Node.js so any help would be appreciated
function getData(){
var http = require('http');
var str = '';
var options = {
host: 'www.random.org',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(response) {
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
});
//return str;
}
var req = http.request(options, callback).end();
// These just return undefined and empty
console.log(req.data);
console.log(str);
}
Of course your logs return undefined : you log before the request is done. The problem isn't scope but asynchronicity.
http.request is asynchronous, that's why it takes a callback as parameter. Do what you have to do in the callback (the one you pass to response.end):
callback = function(response) {
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(req.data);
console.log(str);
// your code here if you want to use the results !
});
}
var req = http.request(options, callback).end();
Simple Working Example of Http request using node.
const http = require('https')
httprequest().then((data) => {
const response = {
statusCode: 200,
body: JSON.stringify(data),
};
return response;
});
function httprequest() {
return new Promise((resolve, reject) => {
const options = {
host: 'jsonplaceholder.typicode.com',
path: '/todos',
port: 443,
method: 'GET'
};
const req = http.request(options, (res) => {
if (res.statusCode < 200 || res.statusCode >= 300) {
return reject(new Error('statusCode=' + res.statusCode));
}
var body = [];
res.on('data', function(chunk) {
body.push(chunk);
});
res.on('end', function() {
try {
body = JSON.parse(Buffer.concat(body).toString());
} catch(e) {
reject(e);
}
resolve(body);
});
});
req.on('error', (e) => {
reject(e.message);
});
// send the request
req.end();
});
}
Shorter example using http.get:
require('http').get('http://httpbin.org/ip', (res) => {
res.setEncoding('utf8');
res.on('data', function (body) {
console.log(body);
});
});
from learnyounode:
var http = require('http')
http.get(options, function (response) {
response.setEncoding('utf8')
response.on('data', console.log)
response.on('error', console.error)
})
'options' is the host/path variable
from learnyounode:
var http = require('http')
var bl = require('bl')
http.get(process.argv[2], function (response) {
response.pipe(bl(function (err, data) {
if (err)
return console.error(err)
data = data.toString()
console.log(data)
}))
})
I think it's too late to answer this question but I faced the same problem recently my use case was to call the paginated JSON API and get all the data from each pagination and append it to a single array.
const https = require('https');
const apiUrl = "https://example.com/api/movies/search/?Title=";
let finaldata = [];
let someCallBack = function(data){
finaldata.push(...data);
console.log(finaldata);
};
const getData = function (substr, pageNo=1, someCallBack) {
let actualUrl = apiUrl + `${substr}&page=${pageNo}`;
let mydata = []
https.get(actualUrl, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', async () => {
if (JSON.parse(data).total_pages!==null){
pageNo+=1;
somCallBack(JSON.parse(data).data);
await getData(substr, pageNo, someCallBack);
}
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}
getData("spiderman", pageNo=1, someCallBack);
Like #ackuser mentioned we can use other module but In my use case I had to use the node https. Hoping this will help others.
This is my solution, although for sure you can use a lot of modules that give you the object as a promise or similar. Anyway, you were missing another callback
function getData(callbackData){
var http = require('http');
var str = '';
var options = {
host: 'www.random.org',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(response) {
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
callbackData(str);
});
//return str;
}
var req = http.request(options, callback).end();
// These just return undefined and empty
console.log(req.data);
console.log(str);
}
somewhere else
getData(function(data){
// YOUR CODE HERE!!!
})

Make HTTP get request

I am trying to make a HTTP get request, but nothing is being returned as text. Here is my code
const http = require('http');
const ws = require('ws');
const wss = new ws.Server({noServer: true});
var XMLHttpRequest = require('xhr2');
function accept(req, res) {
console.log("got request")
wss.handleUpgrade(req, req.socket, Buffer.alloc(0), function(ws) {
//party name, sockets on party, limit 2
ws.on('message', function (msg) {
var message = JSON.parse(msg.toString())
if(message.type==='add') {
//do later
} else if(message.type==='start') {
httpGetAsync('192.168.26.23', "/startRelay")
} else if(message.type==='stop') {
httpGetAsync('92.168.26.23', "/stopRelay")
} else if(message.type==='status') {
httpGetAsync('92.168.26.23', "/")
}
});
ws.on('close', function () {
console.log('closed')
});
ws.on('error', function(error){
console.log('error - ' + JSON.stringify(error));
});
})
}
function httpGetAsync(theUrl, path) {
var options = {
host: theUrl,
path: path,
method: "GET",
}
callback = async function(response) {
var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(JSON.parse(str));
});
};
http.request(options, callback).end();
}
http.createServer(accept).listen(3000);
Here is what 192.168.26.23 has in it (if you type it up from my wifi onto google, this is what shows - and this data is what I need to get in a string)
{"success":true,"ms_left":0,"relayStarted":false}

node can't set headers after they are sent

i know this question asked many time before but still i'm struggling to figure this out. i have a set of js files. first one is index.js
app.all('/backend/*/*', function(req, res){ // backend/product/getProduct
serviceType = req.params[0];
methodType = req.params[1];
exports.serviceType= serviceType;
exports.methodType= methodType;
main.checkService()
});
in here im extracting the params and call checkService method in main.js file
main.js
function checkService(){
switch(index.serviceType){
case 'product':
product.checkMethod();
break;
default :
console.log('no such service')
}
}
then it move to product.js file
function checkMethod(){
var methodName = index.methodType,
res = index.res,
req = index.req;
switch(methodName){
case 'samplePost':
var body = req.body;
proHan.samplePost(body,function(data,msg,status){
sendRes(data,msg,status);
});
break;
default :
console.log('no such method')
}
function sendRes(jsonObj,msg,status){
var resObj = {
status : status,
result : jsonObj,
message : msg
}
res.json(resObj);
}
first it moves to samplePost method in handler.js
once the http req finised executing, callback return the results and call sendRes method and send the json
function samplePost(jsonString,cb){
var res = config.setClient('nodeSample');
// jsonString = JSON.parse(jsonString);
res.byKeyField('name').sendPost(jsonString,function(data,msg,status){
cb(data,msg,status);
});
}
to send http req i written a common file. that is config.js
function setClient(_cls){
var client = new Client(url);
return client;
}
function parentClient(url){
this.postBody = {
"Object":{},
"Parameters":{
"KeyProperty":""
}
};
}
function paramChild(){
parentClient.apply( this, arguments );
this.byKeyField = function(_key){
this.postBody.Parameters.KeyProperty = _key;
return this;
}
}
function Client(url){
parentClient.apply( this, arguments );
this.sendPost = function(_body,cb){
_body = (_body) || {};
this.postBody.Object = _body;
var options = {
host : 'www.sample.com',
port : 3300,
path: '/somrthing',
headers: {
'securityToken' : '123'
}
};
options.method = "POST";
var req = http.request(options, function(response){
var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
cb(JSON.parse('[]'),'success',200)
});
});
//This is the data we are posting, it needs to be a string or a buffer
req.on('error', function(response) {
cb(JSON.parse('[]'),response.errno,response.code)
});
req.write(JSON.stringify(this.postBody));
req.end();
}
}
paramChild.prototype = new parentClient();
Client.prototype = new paramChild();
when i send the first req its work but from then again the server crashes. it seems like i can't call res.end method again in a callback method. how can i fix this. thank you.
you can't call res.end two times. Here is a simple exemple to deal with callback with a basic node server.
const http = require('http');
const hostname = '127.0.0.1';
const port = 4242;
let something = true;
function callback(req, res) {
something = !something;
res.setHeader('Content-Type', 'text/plain');
res.end('Callback Hello World\n');
}
const server = http.createServer((req, res) => {
res.statusCode = 200;
if (something) {
callback(req, res);
} else {
something = !something;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});

How to run a http.request inside a imported module. Its not running when I am trying to access

My main.js file:
var spaceJson = require('./space.js');
var options = {
"method": "GET",
"hostname": "10.10.111.226",
"port": null,
"path": "/API/Org",
"headers": {
"authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbG...",
"cache-control": "no-cache"
}
};
var JSONdata = spaceJson.space.getSpaceData(options);
my space.js file(this actually is making a request to a web api and returns json)
var module = module.exports = {};
var http = require("http");
module.space = {
sayHelloInSpanish: function() {
return "Hola";
},
getSpaceData : function(options) {
var body = '';
http.request(options, function (req,res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
body = Buffer.concat(chunks);
console.log(body.toString());
});
req.end();
});
//return http.get();
}
};
var require = function(path){
return module.exports;
};
when I call
sayHelloInSpanish
method, it returns "holla" when I run main.js. But when I call the
getSpaceData
I dont see anything on command line and it hangs. Maybe I am not handling callback. With this I basically want to consume JSON data in my main.js
You don't see anything because The HTTP response is async.
You should return a callback or use a promise:
getSpaceData : function(options, clbk) {
var body = '';
http.request(options, function (req,res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
body = Buffer.concat(chunks);
console.log(body.toString());
clbk(body.toString());
});
req.end();
});
}
spaceJson.space.getSpaceData(options, function(data){
console.log(data);
});
I recommend you to watch this video: https://vimeo.com/96425312
-- UPDATE --
Delete the require code:
var require = function(path){
return module.exports;
};
add to main:
// main.js
var spaceJson = require("./space.js");

Async with http Node.js

I have 2 asynchronous functions on gives me some urls and other one gives me the content I need from the url and one that writes the content I need to an file, but it write to file first and then it gives me the content I need to write, how can I get him to write to file after I get the content I need. Thanks
var http = require('http');
var fs = require('fs');
var list = {};
var k = 0;
function getContent(url){
var options = {
host: 'www.exammple.org',
path: url
}
var request = http.request(options, function (res) {
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
list[k] = data;
k++;
});
});
request.on('error', function (e) {
console.log(e.message);
});
request.end();
}
var options = {
host: 'www.example2.org',
path: '/mypath'
}
var request = http.request(options, function (res) {
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
///Here I get some urls from data
data = data.split(";");
for(key in data){
data = data.split('href=\"')[1].split('"')[0];
getContent(data[key]);
}
writeToFile();
}
});
});
request.on('error', function (e) {
console.log(e.message);
});
function writeToFile(){
fs.writeFile("file.txt", JSON.stringify(list), function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved");
}
});
}
request.end();

Categories