JSON object from HTTP response there but undefiend - json

In Node.js, I use request to post as such:
First I make the options
var ops = {
'user':'johnny',
'password':'password'
};
Then I make the request as such:
request.post({url: endpoint, formData: ops}, function(err, res, body){
console.log(res.body);
});
This then returns the data I want from an API:
{"user":"johnny","time":"2016-11-03T15:58:34.444Z"}
But then when I change the request to:
request.post({url: endpoint, formData: ops}, function(err, res, body){
console.log(res.body.user);
});
I get back "undefined".
Why can I access the res.body but not then then res.body.user when user is clearly an attribute of the object?
Thanks

Your response being a string, this will do the trick :
var data = JSON.parse(res.body);
console.log(data.user);

Related

Why is my Axios get request getting the entire array instead row associated with the param I pass in?

I am using Axios requests to retrieve data from MySQL with an express server in between.
I have an API route of 'http://localhost:3001/find' which displays the following json when accessed:
[{"id":1,"title":"book title 1","author":"book author 1",},
{"id":2,"title":"book title 2","author":"book author 2"}]
I am trying to retrieve the singular row with the id of 1, so am doing this get request:
const searchMe = () => {
Axios.get('http://localhost:3001/find', {
params: {
"id": "1"
}
})
.then(function (response) {
console.log(response);
})
}
However when I console log the response I get both rows instead of just the one. Is is possible the param isn't getting read properly or something?
EDIT: Here is the code in my express server for handling the 'find' request:
app.get('/find', (req, res)=>{
const sqlInsert = "SELECT * FROM songs;"
db.query(sqlInsert, (err, result)=> {
res.send(result)
// console.log(result);
})
});
I know it definitely works because it is returning the data.

I'm not using Express, but I'm trying extract POST data then to send a json as response, with no luck

I'm still very new to node.js so please bear with me.
I'm trying to extract POST data then sent a json as response, but I don't seem to be able to extract the data from the POST request and even worse I can't find the syntax for people who are NOT using Express to send the json. It keeps telling me res.json is not a function.
EDIT: I found out the problem for the json part, I was a dump. I finally remember what I was told, json are sent like strings.
var http = require('http');
var qs = require("querystring");
server = http.createServer(function (req, res) {
try {
var body = "";
var post = qs.parse("");
if (req.method == "POST") {
res.writeHeader(200, {"Content-Type": "application/json"});
req.on("data", function (data) {
body += data;
console.log(data); //It gives something like <Buffer xx xx xx ...>
if (body.length > 1e6)
req.connection.destroy();
});
req.on("end", function () {
post = qs.parse(body);
console.log(post.test); //It gives "undefined"
});
res.end(JSON.stringify({ a: 1 }));
} catch(err) {
console.dir(err);
res.writeHeader(200, {"Content-Type": "text/plain"});
res.end("Hi hi");
}
});
server.listen(8000);
console.log("http start #8000");
Any help? Thanks in advance.
below solves the date to string (i.e. converting buffer to string
res.on('data', function(chunk) {
var textChunk = chunk.toString('utf8');
// console.log(textChunk); // will give you a stream of text from data
});
you could store textChunk out of the ondata handler, to then use that if required (say returning relevant data to the user back again)

Express Multiple res.json(); with middlewares

I'm trying to build a stateless API using JWT. I have a middleware function in my Router which checks if the JWT has expired, if it has, a new Token with a new timestamp is generated on the fly.
I would like to pass the new token along with the response in the JSON Object. My current approach is like this, but it of course doesn't work:
router.use(function (req, res, next) {
// JWT Expired
// Generate new JWT
res.write(JSON.stringify({token: token});
next();
});
router.get('/securedRoute' function(req, res) {
// Fetch data
res.json({data: data});
});
:
// Output should be:
{token: 'erg34jlkgjre.3f4fknlj.34f3', data: ['sdfa', 'sdf']}
It would be nice to find a way, where I don't have to alter all of my existing code and check if there is a new token.
Thanks for your help!
One option would be to add the authorization token in the response header:
router.use((request, response, next) => {
response.setHeader('Token', token);
next();
});
router.get('/securedRoute', (request, response) => {
response.json({ data: data });
});
Alternatively, you could always add the token to the request and then conditionally add the request.token into all of your routes like the previous answer suggested. Unfortunately that would mean that you need to modify all of your routes.
As an alternative you could override the response.json method and manually inject the token if it exists. In doing so, you wouldn't need to modify any of your routes.
router.use((request, response, next) => {
request.token = token;
((proxied) => {
response.json = function (data) {
if (request && request.token) {
data.token = request.token;
}
return proxied.call(this, data);
};
})(response.json);
next();
});
router.get('/securedRoute', (request, response) => {
response.json({ data: data });
});
In the example above, the response.json method is overridden in the middleware. This is done by passing a reference to the old response.json method and then calling it after conditionally injecting the token into the payload.
The answer is assuming you want to achieve that in same method
Rather than writing the token in middleware do something like
(req,res,next)=>{
req.token = newToken;
next();
}
And in your route
res.json(req.token ? {token:req.token,data:data} : {data:data});

frisby and read the response header with json response REST API

I am using frisby to automate the REST API testing. All of my REST API is based on json and return json response. In one of the requirement, I need to read the response header and fetch the response header and set it for next request. With json response, I am not able to read the response header. Following is sample code for my test.
frisby.create("Check to make sure that user does exist")
.get(hostURL + "/api/users/checkusername/" + username, user, {json: true}, {headers: {'Content-Type': 'application/json'}})
.expectHeaderContains('content-type', 'application/json')
.afterJSON(function (response) {
//How to read session id from header
//var sessionId = res.headers[constants.SESSION_ID_HEADER_KEY];
var exist = response.exist;
expect(exist).toBe(true);
});
Please help.
You code was actually OK, you were just trying to use 'res' variable instead of response.
frisby.create("Check to make sure that user does exist")
.get(hostURL + "/api/users/checkusername/" + username, user, {json: true}, {headers: {'Content-Type': 'application/json'}})
.expectHeaderContains('content-type', 'application/json')
.afterJSON(function (response) {
var sessionId = response.headers[constants.SESSION_ID_HEADER_KEY];
// Use the sessionId in other frisby.create(...) call
}).
toss();
Another alternative is to use after() as follows:
frisby.create("Check to make sure that user does exist")
.get(hostURL + "/api/users/checkusername/" + username, user, {json: true}, {headers: {'Content-Type': 'application/json'}})
.expectHeaderContains('content-type', 'application/json')
.after(function (err, res, body) {
var obj = JSON.parse(body);
var sessionId = obj.headers[constants.SESSION_ID_HEADER_KEY];
// Use the sessionId in other frisby.create(...) call
}).
toss();

how to print json array in html return by node.js

i return the array from node.js
reading xml content from txt file and store in array send to html page using ajax method how do this task.
xml2js = require('xml2js');
fs = require('fs');
var arr={};
var parser = new xml2js.Parser();
fs.readFile('D:/test.txt', function(err, data) {
parser.parseString(data, function (err, result) {
arr=result.Cluster.Array[0].String;
});
});
app.get('/test', function(req, res, next) {
res.json({ message: arr }); //passing array data
});
how to display in html page current i used. But i get whole data in console log not able to display in html page get message undefined :
$.ajax({
url: '/test',
complete: function(data) {
JSON.stringify(data);
console.log(data.message);
// document.write(data.message);
for(i=0;i<data.length;i++)
{
document.write(data.message[i].Val);
$('#did').append('<h1>'+data.message[i].Name+'</h1>');
}
}
use a ReadStream, and stream it into your httpResponse
stream = fs.createReadStream "path/to/file.json"
stream.pipe(res)