Stream application/json POST request - node.js

I have working code to buffer a .json file and then POST that data to a server.
fs.readFile(filePath, 'utf-8', function (err, buf) {
if(err){
reject(err);
}
else{
const req = http.request({
method: 'POST',
host: 'localhost',
path: '/event',
port: '4031',
headers: {
'Content-Type': 'application/json',
'Content-Length': buf.length
}
});
req.on('error', reject);
var data = '';
req.on('response', function (res) {
res.setEncoding('utf8');
res.on('data', function ($data) {
data += $data
});
res.on('end', function () {
data = JSON.parse(data);
console.log('data from SC:', data);
//call fn on data and if it passes we are good
resolve();
});
});
// write data to request body
req.write(buf);
req.end();
}
});
what I would like to do instead is to avoid buffering it, and just use fs.createReadStream, something like so:
fs.createReadStream(filePath, 'utf-8', function (err, strm) {
if(err){
reject(err);
}
else{
const req = http.request({
method: 'POST',
host: 'localhost',
path: '/event',
port: '4031',
headers: {
'Content-Type': 'application/json',
// 'Content-Length': buf.length
}
});
req.on('error', reject);
var data = '';
req.on('response', function (res) {
res.setEncoding('utf8');
res.on('data', function ($data) {
data += $data
});
res.on('end', function () {
data = JSON.parse(data);
console.log('data from SC:', data);
//call fn on data and if it passes we are good
resolve();
});
});
// write data to request body
req.write(strm);
req.end();
}
});
but that doesn't quite work? Is it possible to do this?

This seems to work, but not sure if it's 100% correct
const strm = fs.createReadStream(filePath);
const req = http.request({
method: 'POST',
host: 'localhost',
path: '/event',
port: '4031',
headers: {
'Content-Type': 'application/json',
}
});
req.on('error', reject);
var data = '';
req.on('response', function (res) {
res.setEncoding('utf8');
res.on('data', function ($data) {
data += $data
});
res.on('end', function () {
data = JSON.parse(data);
resolve();
});
});
// write data to request body
strm.pipe(req);

Related

Wait for http post to end using promise

I am learning to use http post and trying to wait for it to end using promise. But I can't get it to work, please help:
var http = require('http');
const auth = () => {
var post_data = JSON.stringify({
"username": "aaa",
"password": "bbb"
});
const options = {
host: 'http://1.1.1.1',
path: '/v1/authentication',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length
}
};
const req = http.request(options, (res) => {
res.setEncoding('utf8');
var body = '';
res.on('data', d => {
body += chunk;
});
res.on('end', function() {
console.log("Response body", body);
});
});
req.on('error', error => {
console.error("error", error);
});
req.write(post_data)
req.end();
return Promise.resolve("!!");
};
exports.helloWorld = (req, res) => {
let message = req.query.message || req.body.message || 'Hello World!';
return auth().then((res)=>{
res.status(200).send(res);
});
};
Entry point is the hellWorld function. What should I do to wait for the http post to finish and get the response result using promise?
here i did some for get api call.
try {
const auth = () => {
return new Promise((resolve, reject) => {
const options = {
host: 'api.github.com',
path: '/orgs/nodejs',
port: 443,
method: 'GET',
headers: {
'User-Agent': 'request'
}
};
const req = https.request(options, (res) => {
res.setEncoding('utf8');
res.on('data', d => {
resolve(d)
});
});
req.on('error', error => {
console.error("error", error);
});
req.end();
})
};
const data = await auth()
console.log('should execute first', data)
console.log('should executed after http call')
} catch (e) {
console.log(e)
}
you can modify above code with your, just you have to wrap your http call inside Promises.
comment down if any its a solution, and mark as a solution

How to chain http.request()

I need to use require('http') (I cannot use other libraries), and I am trying to figure out how I would chain multiple http.request() together?
In my example below, I am trying to create a household with 4 people, and each person will have a pet associated to them. I have 3 routes that will createFamily, createPerson, and createPet. I also have the method createHousehold() that will take the ID's from the response of each route, and pass it down the chain (family -> person -> pet). I am not sure how I would be chaining the response of each route, and passing down the ID.
const http = require('http');
createHousehold('Smith', 4); // Creates 'Smith' family with 4 people, and each member has one pet
// Not sure how to chain requests
function createHousehold(surname, numberOfPeople) {
createFamily(surname)
.then(familyId => {
for (let i = 0; i < numberOfPeople; i++) {
createPerson(familyId)
.then(personId => createPet(personId));
}
});
}
function createFamily(surName) {
const data = JSON.stringify({
config: { surName }
});
const options = {
host: 'myProxyHost.com',
port: '8080',
path: '/v1/family',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
},
};
const request = http.request(options, response => {
let data = '';
response.on('data', chunk => data += chunk);
return (response.on('end', () => JSON.parse(data).id));
});
request.on('error', error => console.log('ERROR - createFamily(): ', error.message));
request.write(data);
request.end();
return request;
}
function createPerson(familyId) {
const data = JSON.stringify({
config: { familyId }
});
const options = {
host: 'myProxyHost.com',
port: '8080',
path: '/v1/person',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
},
};
const request = http.request(options, response => {
let data = '';
response.on('data', chunk => data += chunk);
return (response.on('end', () => JSON.parse(data).id));
});
request.on('error', error => console.log('ERROR - createPerson(): ', error.message));
request.write(data);
request.end();
return request;
}
function createPet(personId) {
const data = JSON.stringify({
config: { personId }
});
const options = {
host: 'myProxyHost.com',
port: '8080',
path: '/v1/pet',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
},
};
const request = http.request(options, response => {
let data = '';
response.on('data', chunk => data += chunk);
return (response.on('end', () => JSON.parse(data).id));
});
request.on('error', error => console.log('ERROR - createPet(): ', error.message));
request.write(data);
request.end();
return request;
}
For example with a proxy server, you would pipe one request (readable) into another request (writable).
If you are just doing serial requests, I would just wrap them in a promise, or use the async library.
function createPet(personId) {
return new Promise((resolve,reject) => {
const data = JSON.stringify({
config: { personId }
});
const options = {
host: 'myHost.com',
port: '8080',
path: '/v1/pet',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
},
};
const request = http.request(options, response => {
let data = '';
response.on('data', chunk => data += chunk);
response.once('end', () => resolve(data)); // ! resolve promise here
});
request.once('error', err => {
console.log('ERROR - createPet(): ', err.message || err);
reject(err); // ! if promise is not already resolved, then we can reject it here
});
request.write(data);
request.end();
});
}
and use it like so:
createHousehold(id)
.then(createFamily)
.then(createPerson)
.then(createPet);
if you want to do things in parallel, then use Promise.all()..or use the async library.
For seeding a database, I highly recommend async.autoInject, you will quickly see why:
https://caolan.github.io/async/v2/docs.html#autoInject
you can use it like so:
const seedDatabase = () => {
return async.autoInject({ // returns a promise
async createHouseHold(){
return somePromise();
},
async createFamily(createHouseHold){
return somePromise();
},
async createPerson(createFamily){
return somePromise();
},
async createPet(createPerson){
return somePromise();
}
});
}

Why Http request never ends

I am doing http request in nodejs, but the request never ends and proceed to do its following code. it only prints out "response end", but never "request end". Why will it behave like this?
const post_data = JSON.stringify({
'username': username,
'org': orgName,
'peers': peers,
'channelName': channelName,
'chaincodeName': chaincodeName,
'fcn': fcn,
'args': args
});
var post_options = {
host: 'localhost',
port: '3000',
path: '/cc/write',
method: 'POST',
headers: {
"content-type": "application/json",
"Content-Length": Buffer.byteLength(post_data)
}
};
var post_req = http.request(post_options, function (res) {
console.log("connected");
res.on('data', function (chunk) {
console.log('Response: ' + chunk);
ccResponse = chunk;
});
res.on('end', function () {
console.log('response end')
});
});
// post the data
post_req.write(post_data);
post_req.on('end', function () {
console.log('request end');
});
post_req.on('finish', function () {
console.log('request end');
});
post_req.end();
console.log("Random thing");
There is an extra bracket right above the last line console.log("Random thing");
After removing that bracket the code produced this log:
Random thing
request end
connected
Response: {"error":"Not Found"}
response end
As you can see there is 'request end' in the log.
It was run with node v11.13.0.
Please let me know if it doesn't help.
The actual code that I used:
const http = require('http');
const post_data = JSON.stringify({
'username': 'username',
'org': 'orgName',
'peers': 'peers',
'channelName': 'channelName',
'chaincodeName': 'chaincodeName',
'fcn': 'fcn',
'args': 'args'
});
var post_options = {
host: 'localhost',
port: '3000',
path: '/cc/write',
method: 'POST',
headers: {
"content-type": "application/json",
"Content-Length": Buffer.byteLength(post_data)
}
};
var post_req = http.request(post_options, function (res) {
console.log("connected");
res.on('data', function (chunk) {
console.log('Response: ' + chunk);
ccResponse = chunk;
});
res.on('end', function () {
console.log('response end')
});
});
// post the data
post_req.write(post_data);
post_req.on('end', function () {
console.log('request end');
});
post_req.on('finish', function () {
console.log('request end');
});
post_req.end();
console.log("Random thing");

Unable to parse InputStreamResource response in nodejs

How to read InputStreamResource in nodejs?
Our REST API returns response as InputStreamResource. We need to convert this response as xlsx file or json format. Please help
Below is the code:
var options = {
host: 'xxxxxxxxxxxxxxxxx',
port: xxxxx,
path: '/eeeeee/axxxxxxx?code=' + req.query.code,
method: 'GET',
headers:{
'user_id': req.headers.user_id,
'access_token': req.headers.access_token
}
};
var req = https.request(options, function (res) {
var decoder = new StringDecoder('utf8');
res.on('data', function(chunk) {
console.log(chunk)
var textChunk = decoder.write(chunk);
console.log(textChunk)
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
Response is getting this way ...
enter image description here
var req = https.request(options, function (res) {
var resData = ''
res.setEncoding('binary')
res.on('data', function(chunk){
resData += chunk
})
res.on('end', function(){
// fs.writeFile('message1.xlsx', resData, 'binary', function(err){
// if (err) throw err
// console.log('File saved.')
// })
var new_wb = XLSX.read(resData, {type:'binary'});
console.log('File saved.');
})
});

How do I wait for a json to load before using it on node.js? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
[EDIT]
I figured it out. The code ends up like this:
//getTrelloJSON.js
var request = require('request');
'use strict';
function getProjJSON(requestURL, callback){
request.get({
url: requestURL,
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 {
callback(data);
}
});
}
module.exports.getProjJSON = getProjJSON;
And
//showData.js
var getJSON = require('./getTrelloJSON');
getJSON.getProjJSON('https://trello.com/b/saDpzgbw/ld40-gem-sorceress.json', (result) => {
var lists = result.lists;
console.log(lists);
});
I run node showData.js and it gets the json and then I can manipulate it as needed. I printed just to show it works.
[EDIT END]
I'm new to node.js and I am facing a noob problem.
This code is supposed to request a JSON from a public trello board and return an object with a section of trello's json (lists section).
The first console.log() does not work but the second does.
How do I make it wait for the completion of getProjJSON() before printing it?
var request = require('request');
'use strict';
//it fails
console.log(getProjJSON('https://trello.com/b/saDpzgbw/ld40-gem-sorceress.json'));
function getProjJSON(requestURL){
request.get({
url: requestURL,
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 {
//it works
console.log(data.lists);
return data.lists;
}
});
}
Node.js is all about callbacks.
And here you just not register the callbacks for data.
var client = require('http');
var options = {
hostname: 'host.tld',
path: '/{uri}',
method: 'GET', //POST,PUT,DELETE etc
port: 80,
headers: {} //
};
//handle request;
pRequest = client.request(options, function(response){
console.log("Code: "+response.statusCode+ "\n Headers: "+response.headers);
response.on('data', function (chunk) {
console.log(chunk);
});
response.on('end',function(){
console.log("\nResponse ended\n");
});
response.on('error', function(err){
console.log("Error Occurred: "+err.message);
});
});
or here is a full example, hope this solve your problem
const postData = querystring.stringify({
'msg' : 'Hello World!'
});
const options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
const req = http.request(options, (res) => {
console.log(`res_code: ${res.statusCode}`);
console.log(`res_header: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`res_data: ${chunk}`);
});
res.on('end', () => {
console.log('end of response');
});
});
req.on('error', (e) => {
console.error(`response error ${e.message}`);
});
//write back
req.write(postData);
req.end();

Resources