node and express send json formatted - json

I'm trying to send formatted json with express.
Here is my code:
var app = express();
app.get('/', function (req, res) {
users.find({}).toArray(function(err, results){
// I have try both
res.send(JSON.stringify(results, null, 4));
// OR
res.json(results);
});
});
I get the json in my browser but it's a string.
How can I send it so it's readable in the browser?

try to set the "secret" property json spaces on the Node app.
app.set('json spaces', 2)
This statement above will produce indentation on json content.

You're going to have to set the Content-Type to application/json like this
app.get('/', function (req, res) {
users.find({}).toArray(function(err, results){
res.header("Content-Type",'application/json');
res.send(JSON.stringify(results, null, 4));
});
});

Use type('json') to set Content-Type and JSON.stringify() for formatting:
var app = express();
app.get('/', (req, res) => {
users.find({}).toArray((err, results) => {
res.type('json').send(JSON.stringify(results, null, 2) + '\n');
});
});

Sending JSON output as formatted from the server could be undesirable considering resource usage and performance of the server. Especially in production environments.
Instead, you can find a few ways to format the JSON output at client-side.
If you are using Chrome, you can use an extension among JSON Formatter, JSON Viewer, JSONView or others from Chrome web store.
Firefox provides built-in JSON viewer since Firefox 44.
When using curl or wget in a command line or a shell script, you can pipe the result in JSON into jq.
$ curl http://www.warehouse.com/products | jq .

This should solve your problem
var app = express();
app.set('json spaces', 4)
app.get('/', function (req, res) {
users.find({}).toArray(function(err, results){
res.json(JSON.parse(results));
});
});

For convenience, you can override res.json in a custom middleware that runs before your routes.
To auto-format all JSON responses:
app.use('*', (req, res, next) => {
res.json = (data) => res.type('json').send(JSON.stringify(data, null, 4))
next()
})
app.get('/route', (req, res) => res.json({ formatted: true })
To allow custom formatting based on individual routes or other logic:
app.use('*', (req, res, next) => {
res.json = (...args) => res.type('json').send(JSON.stringify(...args))
next()
})
app.get('/tabs', (req, res) => res.json({ formatted: 'tabs' }, null, '\t')
app.get('/spaces', (req, res) => res.json({ formatted: 'spaces' }, null, 4)
app.get('/minified', (req, res) => res.json({ formatted: false })

Maybe you need to JSON.parse(resp)

Related

How to dynamically fetch JSON based on param in express

I'm new to node and express but trying to dynamically fetch JSON based on the user's language settings. I need to figure out how to serve up the params:
I was thinking to try and set the "lang" param to its own variable and return that, but I am reading on SO that this is not best practice: Use variable's value as variable in javascript
var express = require("express");
var english = require('./Data/english.json');
var spanish = require('./Data/spanish.json');
var app = express();
app.use(function (req, res, next) {
console.log('inside of app.use');
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-
With, Content-Type, Accept");
next();
});
app.get("/:lang", function (req, res, next) {
const lang = req.params.lang;
console.log(lang)
res.send(lang);
});
app.listen(5000, () => console.log('Listening on port 5000!'))
I would like to be able to dynamically return the appropriate json file ! Any thoughts much appreciated.
TL;DR
Use the fs module to read you JSON files
Call JSON.parse() to parse the raw JSON
Choose the file according to var lang = req.params.lang using some kind of logic (for example, 'spanish' -> './data/spanish.json')
Code
const fs = require('fs');
// Supported languages
const supportedLanguages = ['english', 'spanish'];
app.get("/:lang", function (req, res, next) {
const lang = req.params.lang;
if (supportedLanguages.indexOf(lang) === -1) {
res.status(400).send('Language not supported');
} else {
fs.readFile(`./Data/${lang}.json`, (err, data) => {
// If error send a 500 status
if (err) res.status(500).send(err);
// Else parse the JSON file and send it
else res.send(JSON.parse(data));
});
}
});
It's simple to return json data with express.
Just use res.json({key: value , key2: value2}) instead of res.send
In your case, you can
const language = req.params.lang;
res.json({lang: lang})
you will receive a JSON object instead of text

HTML is being sent instead of JSON Data

I'm trying to retrieve data from a SQL database and display that said data on a Reactjs web app. However, all the calls I make to the database results in the HTML of the webpage in focus. I have set the headers, and I've tried to change the way the response from the express call is being handled.
Here is the expressjs script I am using right now:
const express = require('express');
const sql = require('mssql/msnodesqlv8');
const bodyParser = require('body-parser');
const path = require('path');
const cors = require('cors');
const db = require('./db.js');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use('/counselling/triageadmin/', express.static(path.join(__dirname, '/build')));
app.use(cors());
app.get('/getTable', function (req, res, next){
var request = new sql.Request(db);
request.query('select * from Counselling order by TicketID desc', (err, result) =>{
if (err) { return next(err); }
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(result["recordset"]));
});
});
From there, my axios calls look like this:
componentWillMount(){
let self = this;
axios.get("/getTable")
.then(function (response){
console.log(response.data);
self.setState({
data: response.data,
});
})
.catch(function (error){
console.log(error);
})
}
I added the console.log to check what was being returned, and as said, it was the HTML code of the current page of focus.
I made some changes to reflect what steps I took to get the 500 issue out. The current code, however, results in a 404.
If you move your get on top of your put it should work. The problem seems to be that the static clause resolves your request before it gets to your endpoint, so if you do this:
app.get('/counselling/triageadmin/getTable', function (req, res, next){
var request = new sql.Request(db);
request.query('select * from Counselling order by TicketID desc', (err, result) =>{
if (err) { return next(err); }
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(result["recordset"]));
});
});
app.use('/counselling/triageadmin/', express.static(path.join(__dirname, '/build')));
the path to the get will attempt to be matched before you're routed to your static files.
Ideally you would want to have your rest endpoints under a different namespace, i.e. /api but if you decide to keep your setup, this should help.
I think your routes might be conflicting with each other. From the express documentation at: http://expressjs.com/en/4x/api.html#app.use
// this middleware will not allow the request to go beyond it
app.use(function(req, res, next) {
res.send('Hello World');
});
// requests will never reach this route
app.get('/', function (req, res) {
res.send('Welcome');
});
Thus, your route '/counselling/triageadmin/getTable' will never be reached, because your route '/counselling/triageadmin/' is intercepting it, responding with static resources.
To solve this, try organizing your routes in a way that puts all of your API requests at a different subfolder, like '/api'. So your getTable endpoint would be located at: '/api/counselling/triageadmin/getTable/' or something like that.
I'm also learning the MEAN stack and I stumbled upon your question since I had the opposite problem. I wanted it to respond with an HTML instead of a JSON
this line of code MAKES it respond with an HTML
res.send(JSON.stringify(result["recordset"]));
(I tried res.send("<h3 HTML T_T </h3>");) and it did send and HTML
however, if you try
res.json(String(req.params.id)); <= Notice the res.json instead of res.send
It responds with a JSON :)
I hope this helped

Node.js how to read json data from request?

I have a server as following:
app.post('/', function(req, res, next) {
console.log(req);
res.json({ message: 'pppppppppppppssssssssssssss ' });
});
The request is sent from a client as:
$.ajax({
type: "POST",
url: self.serverURI,
data: JSON.stringify({ "a": "128", "b": "7" }),
dataType: 'json',
success: function (result) {
console.log(result);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr);
}
});
so far the connection fine.
My problem is in the server:
console.log(req);
where I want to read the data I sent. How can I read { "a": "128", "b": "7" } from req?
Although you're not mentioning it, your code looks like it's written for an Express environment. My answer is targeted to this.
Make sure to use body-parser for Express. In case, your project depends on some generated boilerplate code, it's most likely already included in your main server script. If not:
var bodyParser = require('body-parser');
app.use(bodyParser.json());
Installation with npm: npm install body-parser --save
The parsed JSON can then be accessed through req.body:
app.post('/', function(req, res, next) {
console.log(req.body); // not a string, but your parsed JSON data
console.log(req.body.a); // etc.
// ...
});
For Express 4+,
const express = require("express");
const app = express();
app.use(express.json());
Then, you can use req.body as expected.
app.post("/api", (req, res) => {
/*
If the post request included { data: "foo" },
then you would access `data` like so:
*/
req.body.data
...
});

Parsing JSON in Express without BodyParser

I'm trying to write a simple express server that takes incoming JSON (POST), parses the JSON and assigns to the request body. The catch is I cannot use bodyparser. Below is my server with a simple middleware function being passed to app.use
Problem: whenever I send dummy POST requests to my server with superagent (npm package that lets you send JSON via terminal) my server times out. I wrote an HTTP server in a similar fashion using req.on('data')...so I'm stumped. Any advice?
const express = require('express');
const app = express();
function jsonParser(req, res, next) {
res.writeHead(200, {'Content-Type:':'application/json'});
req.on('data', (data, err) => {
if (err) res.status(404).send({error: "invalid json"});
req.body = JSON.parse(data);
});
next();
};
app.use(jsonParser);
app.post('/', (req, res) => {
console.log('post request logging message...');
});
app.listen(3000, () => console.log('Server running on port 3000'));
I think the problem like to get rawBody in express.
Just like this:
app.use(function(req, res, next){
var data = "";
req.on('data', function(chunk){ data += chunk})
req.on('end', function(){
req.rawBody = data;
req.jsonBody = JSON.parse(data);
next();
})
})
And you need catch the error when parse the string to json and need to judge the Content-type of the Req.
Good luck.
another way that worked with me by collecting all chunks into an array and parsing the concatenated chunks.
app.use("/", (req, res, next)=>{
const body = [];
req.on("data", (chunk) => {
console.log(chunk);
body.push(chunk);
});
req.on("end", () => {
const parsedBody = Buffer.concat(body).toString();
const message = parsedBody.split('=')[1];
console.log(parsedBody);
console.log(message);
});
console.log(body);
});
To get access to req.body this worked for me:
app.use(express.json({extended: false}));
In Express v4.16.0 onwards:
app.use(express.json())

Make REST API on Meteor+React without other packages

For example, when the path is
/json/users/4
meteor app must return json something like
{
id: 4,
name: 'Alex'
}
I'm using reactrouter:react-router for client routing. I know about reactrouter:react-router-ssr, but how to use it to response raw json? And make it not conflicting with existing client routing?
I found the answer. Meteor's default Webapp package will help (doc):
WebApp.connectHandlers.use("/hello", function(req, res, next) {
res.writeHead(200);
res.end("Hello world from: " + Meteor.release);
});
I put this in server folder. Other routes will be rendered as they was.
So, there is more useful example (es6):
WebApp.connectHandlers.use("/payme", function(req, res, next) {
res.writeHead(200, {'Content-Type': 'application/json'});
if (req.method === 'POST') {
req.on('data', (chunk) => {
const body = chunk.toString();
if (body.length < 1e6) {
const params = body.split('&').reduce((result, item) => {
const [key, val] = item.split('=');
//do it for utf-8 values (I use it for cyrillic strings)
result[key] = unescape(decodeURI(val)).replace(/\+/g, ' ');
return result;
}, {}); //post method params
//do something and get resulting json
res.end(JSON.stringify(result));
} else
res.end(JSON.stringify({error: 'too big query'}));
});
} else
res.end(JSON.stringify({error: 'isnt post req'}));
});
req.query can be used to get GET params.