I am trying to make a function that returns the content of the webpage and this is what I have so far
var get_contents = function() {
var httpRequestParams =
{
host: "google.com",
port: 80,
path: "/?"
};
var req = http.get(httpRequestParams, function(res)
{
var data = '';
res.on('data', function(chunk) {
data += chunk.toString();
});
//console.log(data);
}).end();
return req;
}
This when I run this code, I see the html contents when the console logging is turned on but when I try to return the output, it just never works.
I can't figure out a way to return get_contents() anywhere. On the console, it just doesnt respond.
Thanks
Something like that: (dont forget to handle error and timeout)
var on_contents = function(cb) {
var httpRequestParams =
{
host: "google.com",
port: 80,
path: "/?"
};
var req = http.get(httpRequestParams, function(res)
{
var data = '';
res.on('data', function(chunk) {
data += chunk.toString();
});
res.on('end', function(){
cb(data);
});
//console.log(data);
}).end();
}
function onFinish(data) {
console.log(data);
}
on_contents(onFinish)
The short answer is: You can't return the data from that function. http.get is asynchronous, so it doesn't actually start running the callback until after your function ends. You'll need to have your get_contents function take a callback itself, check in the http.get handler whether you're done loading and, if you are, call the get_contents callback.
There is an awesome module [request][1] available in node.js.
var request = require('request'),
url = require('url');
var server = http.createServer(function (request, response) {
getPage("http://isohunt.com/torrents/?iht=-1&ihq=life+is+beautiful", function (body) {
console.log(body);
})
});
server.listen(3000);
More information can be found on http://www.catonmat.net/blog/nodejs-modules-request/
Related
I have an application in Node with Express and trying to successfully finish the implementation of a payment system called "Flow".
[EDIT]
I bypassed something very important, it's a function that wraps the functionality that is triggering after the end of the method. I tried making it async so I can wrap the functions then as a promise like someone adviced, but got some errors. I'll re-check.
//REALIZAR PAGO $
app.post('/realizarPago', function(req, res){
var amount = Math.floor(Math.random() * 999999) + 100000;
var paymentMethod = 9;
var urlRedirect = "https://sandbox.flow.cl/app/web/pay.php?token=";
...
//Other relevant variables
var req = https.request(options, function (res) { //<=== This one
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
...
//this is just a sample token that I'll later capture from response
urlRedirect = urlRedirect+"1234567890";
});
});
var postData = qs.stringify({
'flowOrder': flowOrder,
'amount': amount,
...
});
req.write(postData);
res.redirect(307, urlRedirect);
req.end();
});
Everything works almost fine, the problem is that the redirect is executed before urlRedirect updates its value in urlRedirect = urlRedirect+"1234567890";
I've tried with .then() after res.write(postData) executes, with no useful result. I've tried .then() in almost every method, I've also tried with res instead of req and viceversa. I also did some research and found an interesting thing called "waterfall" for async methods but in case of res.on methods can't imagine a way of encapsulating this.
What can I try next?
[EDIT 2]
Thanks to all of your guidance, I was able to use some promises and change the execution order. Now it's doing what I need, now it says that some parameters are missing in the https request. I'll have to fix that. The final code is:
//REALIZAR PAGO $
app.post('/realizarPago', async function(request, response){
var amount = Math.floor(Math.random() * 999999) + 100000;
var paymentMethod = 9;
...
//Other relevant variables
var urlRedirect = "https://sandbox.flow.cl/app/web/pay.php?token=";
var req = https.request(options, (res) => {
var chunks = [];
res.on("data", (chunk) => {
chunks.push(chunk);
});
res.on("end", (chunk) => {
var body = Buffer.concat(chunks);
var datos = body.toString();
datos = JSON.parse(datos);
var token = datos.token;
urlRedirect = urlRedirect+token
response.redirect(urlRedirect);
});
});
req.end();
var postData = qs.stringify({
'flowOrder': flowOrder,
'amount': amount,
...
});
req.write(postData);
req.end();
});
You put the redirect into the end event handler, and you also add an error handler in case the request fails and you change the name of one of the two res arguments so they don't conflict and you can still access both of them. I changed the higher level one to response so it can be used inside the other callbacks where res is already defined:
//REALIZAR PAGO $
app.post('/realizarPago', function(req, response){ // <== change arg name to response
var amount = Math.floor(Math.random() * 999999) + 100000;
var paymentMethod = 9;
var urlRedirect = "https://sandbox.flow.cl/app/web/pay.php?token=";
...
//Other relevant variables
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
...
//this is just a sample token that I'll later capture from response
urlRedirect += "1234567890";
response.redirect(307, urlRedirect); // <== move this here
});
});
req.on('error', err => { // <== add this
console.log(err);
response.sendStatus(500);
});
var postData = qs.stringify({
'flowOrder': flowOrder,
'amount': amount,
...
});
req.write(postData);
req.end();
});
Client function is requesting for data from Server. I imported this function in other file where I need it to use. It is working fine. But i don't understand why I am receiving on command prompt "Undefined". I have commented all console.log but still it is coming. I'm not sure if export/import has problem?
Here is my code:
// tstReq.js
function getData(iccid) {
toString(iccid);
var http = require('http');
var jasParseData;
var options = {
host: 'demo8620001.mockable.io',
port: 80,
path: '/Api3',
method: 'get'
};
http.request(options, function(res) {
//console.log('STATUS: ' + res.statusCode);
//console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
//console.log('BODY: ' + chunk);
josParseData= JSON.parse(chunk);
for(i = 0, len = Object.keys(josParseData.iccid[i]).length; i<=len; i++) {
//console.log('JSON.parse:',josParseData.iccid[i]);
//console.log("iccid: ",iccid);
if (josParseData.iccid[i] === iccid) { // Only printed match iccid
console.log('JSON.parse:',josParseData.iccid[i]);
console.log("iccid: ",iccid);
}
if (josParseData.iccid[i] === iccid) {
console.log("Valid Jasper", i+1);
console.log('\n');
}
else{
// console.log ("Invlid Jasper");
}
//console.log('\n');
}
//console.log('\n');
});
}).end();
};
module.exports = getData;
Here is code where I am using exported function:
const fs = require('fs');
var parse = require('csv-parse');
var validateICCID = require('./funcValidateId.js');
var getData = require('./tstReq.js');
fs.createReadStream('iccid2.csv')
.pipe(parse({delimiter: ':'}))
.on('data',function(csv) {
csvrow= csv.toString();
console.log('\n');
console.log(getData(csvrow));
console.log('\n');
});
You're probably getting undefined because the function getData doesn't have a return statement. It doesn't mean your function is broken, it's just not directly returning a result.
If you want to log the result of getData, you'll need to return http.request, and you'll need to resolve the http.request by returning in the callback.
Also, I noticed you declared var jasParseData you probably meant josParseData.
I have a script that GETS with http.request a website.
I have placed console.log()'s everywhere, yet can't even get it to log.
Here's my code:
var dg = {
hostname: 'www.roblox.com',
path: '/studio/plugins/info?assetId=12313013',
headers: {
'Accept-Encoding': 'gzip'
}
};
var omagawsh = http.request(dg, function(rspn) {
var strn = []
var gunzip = zlib.createGunzip();
rspn.pipe(gunzip)
gunzip.on('error', function(e) {
})
gunzip.on('data', function(chunk) {
strn.push(chunk)
});
gunzip.on('end', function() {
});
omagawsh.on('error', function(e) {
})
omgawsh.end();
})
I am using
var zlib = require('zlib')
var http = require('http')
at the top.
Any help is much appreciated, thanks
You never actually write the request which you would do with omgawsh.end(). The request will not actually be sent until this is done.
var omagawsh = http.request(dg, function(rspn) {
/* snip */
omgawsh.end();
})
Since the request is not done, the response callback is not reached. Your calls to omgawsh should be outside the callback.
var omagawsh = http.request(dg, cb);
omagawsh.on("error", handleError)
omagawsh.end()
See the documentation for http.request: https://nodejs.org/api/http.html#http_http_request_options_callback
I'm fairly new to Node and Javascript and I'm struggling with my first Node module. What I'm trying to do is export functions for specific API calls and I'd like to reuse my https.request function rather than duplicating the code in each function. For some reason I'm failing to wrap my head around how to pass the data back to my original function. Here's an abbreviated version - the listStuff function would be one of many to handle various api request actions.
'use strict';
const https = require('https');
const _ = require('underscore');
const hostStr = 'api.server.net';
function listStuff(){
var pathStr = '/release/api/stuff';
_apiCall(pathStr);
//Would like to handle the https response data here
};
function _apiCall(pathStr){
var options = {
host: hostStr,
path: pathStr
};
var req = https.get(options, function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
var responseString = '';
res.on('data', function(d){
responseString += d;
});
res.on('end', function(){
var responseObject = JSON.parse(responseString);
});
});
req.end();
req.on('error', function(e){
console.log(e);
});
};
module.exports = {
listStuff: listStuff
};
Hope this helps. Register a callback in the apiCall function, and then check the callback params for error handling. Then, just make sure you return the callback when you want to end the function call (either in the on end or on error processing).
function listStuff(){
var pathStr = '/release/api/stuff';
_apiCall(pathStr, function(err, data) {
if (err) // handle err
//handle data.
});
};
function _apiCall(pathStr, callback){
var options = {
host: hostStr,
path: pathStr
};
var req = https.get(options, function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
var responseString = '';
res.on('data', function(d){
responseString += d;
});
res.on('end', function(){
var responseObject = JSON.parse(responseString);
return callback(null, responseObject);
});
});
req.end();
req.on('error', function(e){
console.log(e);
return callback(e);
});
};
A slightly different approach using Promise objects. Note I looked into this as a learning exercise and hope it helps. I have not written all the code for you and the debugging is all yours!
Firstly make _apiCall returns a promise object.
function listStuff()
{
var pathStr = '/release/api/stuff';
var promise = _apiCall(pathStr);
promise.then( function( responceObject){
// handle response object data
});
promise.catch( function( error){
console.log( error.message); // report error
});
}
Next step is to make _apiCall return a promise object for the HTTPS request it will initiate inside the executor of promise creation.
function _apiCall(pathStr)
{ var options = {
host: hostStr,
path: pathStr
};
function beginGet( worked, failed)
{
// see below
}
return new Promise( beginGet);
}
Lastly write beginGet to initiate and call back success or fail functions depending on the outcome of the get request.
function beginGet( worked, failed)
{ var req;
var responseObj;
function getCallBack( res)
{ // all your get request handling code
// on error call failed( error)
// on sucessful completion, call worked(responseObj)
}
req = https.get(options, getCallBack);
}
Also please check with https.get documentation - I think it calls req.end() for you. All the other errors are mine :-)
I want to use app.get to deliver the data from an API on another domain. I can write the data to the console, but nothing is appearing on the page ('~/restresults').
This is the code I have so far:
app.get('/restresults', function (req, res) {
var theresults;
var http = require('http');
var options = {
port: '80' ,
hostname: 'restsite' ,
path: '/v1/search?format=json&q=%22foobar%22' ,
headers: { 'Authorization': 'Basic abc=='}
} ;
callback = function(res) {
var content;
res.on('data', function (chunk) {
content += chunk;
});
res.on('end', function () {
console.log(content);
theresults = content ;
});
};
http.request(options, callback).end();
res.send(theresults) ;
});
how can I bind the result of the http.request to a variable and return it when 'restresults/' is requested?
Move res.send(theresults); to here:
callback = function(res2) {
var content;
res2.on('data', function (chunk) {
content += chunk;
});
res2.on('end', function () {
console.log(content);
theresults = content ;
res.send(theresults) ; // Here
});
};
Note: You'll have to change res to something else as you want the express res, no the request res.
The callback is an asynchronous call. You're sending the response before you get a result from the request.
You'll also want to handle the case in which there is an error, otherwise the client's request may hang.
You are currently sending the response before the callback (from the http request) is done.
The http.request is async, the script will not wait til its done and then send the data back to client.
You will have to wait for the request to be done and then send the result back to the client (preferably in the callback function).
Example:
http.request(options, function(httpRes) {
// Notice that i renamed the 'res' param due to one with that name existing in the outer scope.
/*do the res.on('data' stuff... and any other code you want...*/
httpRes.on('end', function () {
res.send(content);
});
}).end();