fs.writeSync output string as an int array - json

I use express router to catch a ajax post data, which is a stringified JSON obj:
router.all('/ajax/setup/save/asset', function (req, res) {
console.log('POST: /ajax/setup/save/asset');
var fileName = path.join(jsonFileNamePrefix, jsonFileName_asset);
req.on('data', function(chunk) {
console.log('POST: DATA: ' + chunk);
fd = fs.openSync(fileName, 'w');
console.log('Opened file: ' + fileName);
fs.writeSync(fd, chunk);
console.log('Wrote ' + chunk + ' into file ' + fileName);
fs.closeSync(fd);
console.log('Closed file: ' + fileName);
res.end();
console.log('res.end()');
});
});
Then the console logs:
POST: /ajax/setup/save/asset
POST: DATA: {"asset":"test"}
Opened file: /srv/data/asset.json
Wrote {"asset":"test"} into file /srv/data/asset.json
Closed file: /srv/data/asset.json
res.end()
However, the file is actually written as:
[123,34,97,115,115,101,116,34,58,34,116,101,115,116,34,125]
Tried telling fs.writeSync to use 'utf8', 'hex' encoding, still got same result.
Also tried JSON.parse and then JSON.stringify the incoming data chunk, didn't help either..

The req object in your code is actually an instance of the http.IncomingMessage stream.
When it provides information via the data event, this information is provided as a buffer.
Additionally, not all the data for the request is guaranteed to be available in the first call to the handler.
There are several ways to capture this data into a useable string. You could create a new string and simply concat the chunks together
router.all('/ajax/setup/save/asset', function (req, res) {
var buf = ''
req.on('data', function(chunk){
buf += chunk.toString();
});
req.on('end', function(){
console.log(buf);
});
});

Related

Error in parsing form-data in Node Express

I have an express service which has an endpoint that consumes a POST call with form-data in XML.
Postman Call
I'm using multer and express-xml-bodyparser and my index.js looks like:
'use strict';
const express = require('express');
const app = express();
const xmlparser = require('express-xml-bodyparser');
const multer = require('multer')
const upload = multer()
const redact = { redact: ['body.*', 'value.body'] };
const modsRoute = require('./routes/mods');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(xmlparser());
app.use(upload.none());
app.post('/request', modsRoute.postMethod)
module.exports = app;
The problem is that when I try to print the content of the request body in my router method:
const postMethod = async (req, res, next) => {
try {
console.log('body: ', req.body);
res.status(200).send();
} catch (err) {
next(err);
}
};
I get a weird object:
body: [Object: null prototype] {
'api-key': '1a393779-c191-11e3-ae50-80c16e6a4098',
data: '<subscriber>\n' +
'\t<action>add</action>\n' +
'\t<customer_id>529</customer_id>\n' +
'\t<subscriber_details>\n' +
' <unique_id>123UniqueID</unique_id>\n' +
'\t\t<firstname>First</firstname>\n' +
'\t\t<lastname>Test</lastname>\n' +
'\t\t<address1>999 Street</address1>\n' +
'\t\t<address2></address2>\n' +
'\t\t<city>Scottsdale</city>\n' +
'\t\t<state>AZ</state>\n' +
'\t\t<zip>85253</zip>\n' +
' <email>email#infoarmor.com</email>\n' +
' <dob_month>00</dob_month>\n' +
'\t\t<dob_day>00</dob_day>\n' +
'\t\t<dob_year>0000</dob_year>\n' +
'\t\t<phone>9999999999</phone>\n' +
'\t\t<options>\n' +
'\t\t\t<plan_type>1</plan_type>\n' +
' <ew_status>0</ew_status>\n' +
'\t\t</options>\n' +
'\t\t<billing_information>\n' +
'\t\t\t<bill_type>prd</bill_type>\n' +
'\t\t</billing_information>\n' +
'\t</subscriber_details>\n' +
'</subscriber>'
}
As it can be seen, the object contains all the newline and whitespace characters and it hasn't really converted it into JSON.
I also tried to convert the whole body into JSON with JSON.parse() but I got an exception thrown. I also tried to first stringify() the body and then parse it.
In that case, I could only get the data field but I was again an expection when trying to get the api-key field.
Do I need to add any other middleware in order to get at least a correct JSON object of req.body even though the field data is still in XML and not JSON?
You can send json data to user using like this
const postMethod = async (req, res, next) => {
try {
res.json({"Hello":"World"});
// you can send anything json back including req.body like
// this res.json(req.body);
} catch (err) {
next(err);
}
};

How can we generate qr code for json object using nodejs?

Below is an example of converting a text to qr code.
var QRCode = require('qrcode');
var express = require('express');
var connect = express();
connect.get('/', function(req, res){
res.writeHead(200, { 'Content-Type': 'text/html' });
var sometext='hi my name is saurav ghadai';
// QRCode.QRCodeDraw.color.dark = '#d4d4d4';
QRCode.toDataURL(sometext, function (err, url) {
if (err) console.log('error: ' + err)
res.end("<!DOCTYPE html/><html><head><title>node-qrcode</title></head><body><img src='" + url + "'/></body></html>");
});
});
connect.listen(3030);
console.log('test server started on port 3030');
like this how can we create qr code for a json object ?
You can use JSON Strigify method to convert your JSON object into text. Then use the text output into your QR generator method

NodeJS get request. JSON.parse: unexpected token

I'm writing a function in NodeJS that hits an Url and retrieves its json. But I'm getting an error in JSON.parse: unexpected token.
In json validators the string is passing the test when I copy from the browser and paste into the text field, but when I paste the Url for the parser to get the json it show me an invalid message.
I guess it is something with the encoding of the response, but I can;t figure out what it is. Here if my function with an example Url.
function getJsonFromUrl(url, callback)
{
url = 'http://steamcommunity.com/id/coveirao/inventory/json/730/2/';
http.get(
url
, function (res) {
// explicitly treat incoming data as utf8 (avoids issues with multi-byte chars)
res.setEncoding('utf8');
// incrementally capture the incoming response body
var body = '';
res.on('data', function (d) {
body += d;
});
// do whatever we want with the response once it's done
res.on('end', function () {
console.log(body.stringfy());
try {
var parsed = JSON.parse(body);
} catch (err) {
console.error('Unable to parse response as JSON', err);
return callback(err, null);
}
// pass the relevant data back to the callback
console.log(parsed);
callback(null, parsed);
});
}).on('error', function (err) {
// handle errors with the request itself
console.error('Error with the request:', err.message);
callback(err, null);
});
}
Can you help me, please?
Thanks in advance for any help.
Concatenating response as string might have issues with encoding e.g. if buffer of every chunk is converted to string with partial UTF-8 encodings at beginning or end. Thus I'd advise to concatenate as buffer first:
var body = new Buffer( 0 );
res.on('data', function (d) {
body = Buffer.concat( [ body, d ] );
});
Of course it might help to explicitly convert buffer to string on your behalf rather than relying on JSON.parse() doing it implicitly. This might be essential in case of using unusual encoding.
res.on('end', function () {
try {
var parsed = JSON.parse(body.toString("utf8"));
} catch (err) {
console.error('Unable to parse response as JSON', err);
return callback(err, null);
}
...
Aside from that the content delivered by given URL seems to be pretty valid JSON.

Node/Express: Trying to send static JSON file to API endpoint

I am working on a MEAN stack app, and I'm trying to create a couple of API endpoints that the Angular client can $http.get, with simple JSON files populated with dummy data.
Here's the orders.json file I'm trying to test it with:
[
{
"order_status":"Shipped",
"order_qty":30
},
{
"order_status":"Shipped",
"order_qty":6
}
]
For example, the api route to $http.get:
apiRouter.get('/:fileName', queries.getStaticJSONFileForDevelopment);
But when I try to use express's sendFile method with a local .json file, like orders.json:
queries.js:
exports.getStaticJSONFile = function(req, res) {
var fileName = req.params.fileName;
console.log('path: ' + path.normalize(__dirname + '/' + fileName));
res.sendFile(path.normalize(__dirname + '/' + fileName), function(err) {
if (err) return res.send({ reason:error.toString() });
});
};
The console.log tells me I'm pointed at the correct path to the file, but Postman delivers this error:
TypeError: undefined is not a function
at Object.exports.getStaticJSONFile [as handle] (path/to/queries.js:260:7)
// queries.js:260:7 points to the 's' in 'sendFile' above
However, when I just send the json data by itself:
res.send([{"order_status":"Shipped","order_qty":30},{"order_status":"Shipped","order_qty":6}]);
...the endpoint renders the data as you would expect. Am I trying to get the sendFile method to do something it's not meant to do, or is there something I'm missing? Thanks very much for any advice you may have!
If You want to read json file and response with json so You can try this:
var jsonfile = require('jsonfile');
exports.getStaticJSONFile = function(req, res) {
var fileName = req.params.fileName;
var file = path.normalize(__dirname + '/' + fileName);
console.log('path: ' + file);
jsonfile.readFile(file, function(err, obj) {
if(err) {
res.json({status: 'error', reason: err.toString()});
return;
}
res.json(obj);
});
};

Error in parsing json array accepting multiple values

Whenever i am giving a single data element in my json file my code works fine,but as soon as i give an array of elements it starts showing undefined on the client side.
This is my server side code.
var app = require('express')()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server);
var fs= require('fs');
server.listen(3000);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/cli_index.html');
});
io.sockets.on('connection', function (socket) {
var file = __dirname + '/data.json';
fs.readFile(file, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
data = JSON.parse(data);
// You can save those values somewhere or just log them to the console
console.log(data);
socket.emit('news', { hello: data});
});
});
This is my client side code.
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
JSON.stringify(data);
for(var i=0;i<2;i++){
document.write(data[i].hello.name);
}
});
</script>
This is my external json file.
[{"name":"hey"},{"name":"Gouraw"}]
In this server side code:
socket.emit('news', { hello: data});
...you're sending the array as the hello property of an object, but this client-side code:
document.write(data[i].hello.name);
...is expecting the top-level to be an array, with individual hello properties for each entry. Change that to:
document.write(data.hello[i].name);
...so you're indexing into the array.
It would probably be best, as well, to limit your loop using the array's length rather than a hardcoded value:
for(var i=0;i<data.hello.length;i++){