Convert yaml to JSON returns ["object Object"] - node.js

I am building a backend service to convert YAML to JSON. However, it returns ["object Object"].
Postman post request in text: name: wf1
Code:
import { safeLoad } from 'js-yaml'
app.post('/,
function (req, res) {
res.send(JSON.stringify(safeLoad(req.body)))
}
)
Return ["object Object"]
I expect it return JSON format of name: wf1.

You need to make sure the body is actually parsed as raw text if you're intending to send text (i.e. Content-Type: text/plain) in your request. Using the text-function from body-parser should fix this issue:
app.use(bodyParser.text())
app.post('/', (req, res) => {
res.send(JSON.stringify(safeLoad(req.body)));
})
Note that if you're intending to send actual json back to the client you need to change this to:
app.post('/', (req, res) => {
res.json(safeLoad(req.body));
})

First of all, according to js-yaml, safeLoad function only accept String as input type but req.body should return as a object. Maybe point to the particular key can work for you.

Related

Why is body not directly inside Request but can be obtained by parsing raw body buffer?

I'm receiving a webhook from Shopify.
The endpoint is configured like this:
app.post('/webhook-receiver',async (req, res) => {
...function body here
})
When I log the request body like this I get undefined:
console.log(req.body) // returns undefined
But if I do this, I get the body:
import getRawBody from "raw-body"
const bodyBuffer = getRawBody(req);
console.log(JSON.parse(bodyBuffer.toString()); // returns the body expected
What is the reason ?

express-validator converting body to [object Object]

I'm trying to escape form input for a simple demo express app, and I'm getting a result I don't understand.
When I execute this route:
/* Update a toy */
app.post('/toys/:id', [
body().escape()
], (req, res) => {
console.log("Update: ");
console.log(req.body);
toyController.update(req, res);
});
I get this output:
Update:
[object Object]
It looks to me as if the request body is getting destroyed.
If I remove the middleware,
/* Update a toy */
app.post('/toys/:id', (req, res) => {
console.log("Update: ");
console.log(req.body);
toyController.update(req, res);
});
I get the expected result:
Update:
{
toy: {
name: 'Playstation 4',
description: 'A gaming console',
manufacturer: 'Sony',
price: '400'
},
commit: 'Update Toy'
}
Update: If I call body('toy') instead of body(), I get the following result:
{ toy: '[object Object]', commit: 'Update Toy' }
So, it appears that the problem lies in the fact that that body is a nested object.
How can I apply the validation/sanitization to body.toy instead of all of body?
Is there a way that I can directly call the escape code an apply it to a specific string, instead of using the entire middleware setup?
You need to use body().escape() in a correct way. Please refer below an example.
const express = require('express');
const { body } = require('express-
validator');
const app = express();
app.use(express.json());
app.post('/comment', [
body('email')
.isEmail()
.normalizeEmail(),
body('text')
.not().isEmpty()
.trim()
.escape(),
body('notifyOnReply').toBoolean()
], (req, res) => {
// Handle the request somehow
});
Above example contains the right way to use express validator.In the example above, we are validating email and text fields, so we may take advantage of the same chain to apply some sanitization, like e-mail normalization (normalizeEmail) and trimming (trim)/HTML escaping (escape).
The notifyOnReply field isn't validated, but it can still make use of the same check function to convert it to a JavaScript boolean.
Sorry the indentation is not good, I am posting the answer from mobile.
Since you modified the question. You can use schema validation by express- validator.
https://express-validator.github.io/docs/schema-validation.html

I can not get data from the json request

I send JSON data to route:
const data=[{name:this.name}]
//qs.stringify(payload)
axios
.post('/users',{name:this.name})
.then(
response => {
console.log(response.data);
}
)
.catch(
// error=>console.log(error)
)
And try get data:
router.post('/', function (req, res, next) {
var data = req.body; // here is your data
var obj=JSON.parse(data);
console.log(obj.toString());
res.toString("ok");
});
And I got error 500.
Why not get the data?
Your client side code is fine, except that the constant named data is entirely unused. On server-side however, req.body almost certainly contains a parsed JSON object (provided you have included a body paring middleware already). If you haven't included any body parsing middleware then req.body would be undefined.
Additionally, the toString() method in res doesn't send any response, it simply returns a string representation of the response.
You would need to make following changes to your code:
Include a body parsing middleware (eg. body-parser) to your express middleware chain, if one isn't already included.
Don't call JSON.parse(req.body). body-parser would already have done that. Calling it again will only throw exception, and return 500.
To convert an Object to JSON string, use JSON.stringify() method. obj.toString() will probably only return [object Object].
Send response using one of .send(), .json(), .end() methods on res. Since you need to send a string back, res.send("ok") seems most appropriate.
The changed code should appear something like this:
router.post('/', function (req, res, next) {
var data = req.body; // here is your data
console.log(JSON.stringify(data));
res.send("ok");
});

Transforming a payload from requestjs before sending it to the client

Brothers and sisters, I am building an Express API Endpoint that needs to consume an external API, perform some changing of keys and values, and return to the result to the client. Here is what I have thus far:
const external_endpoint = <external_api_end_point>;
app.get('/', function (req, res, next) {
request({ url: external_endpoint}).pipe(res);
});
This returns the exact payload you would get from hitting the external_endpoint directly.
Isn't there something I can do to change res before it gets sent to the client? I tried a few things but nothings has worked. Any ideas or best practices associated with doing a transform on the incoming payload?
For the sake of simplicity. Lets say this is the payload obj.json:
{
"sad": {
"userid": 5,
"username": "jsmith",
"isAdmin": true
}
}
and I am wanting to change sad to happy.
I know outside of the request I could do something like this:
obj = JSON.parse(JSON.stringify(obj).split('"sad":').join('"happy":'));
but throwing obj in place of res will not work. I have tried assigning the value of this res and res.body but no dice.
Thanks for you help in advance!
If you're using request-promise, you can simply make a new response and send it, or modify the response you got back:
app.get('/', function (req, res, next) {
request({ url: external_endpoint, json: true})
.then(response => res.json({ happy: response.sad })))
.catch(next);
});
(of course, you need to handle errors appropriately)
If you want to process it as a stream (which makes sense if you have a massive amount of data), you can use the original request module, and use event-stream to create your pipe:
const es = require('event-stream');
const swapper = es.through(
function write(data) {
this.emit("data", data.replace("sad", "happy"));
},
function end() {
this.emit("end");
}
);
request({ url: external_endpoint})
.pipe(es.stringify())
.pipe(swapper)
.pipe(es.parse())
.pipe(res);
Here's a sandbox to test the stream processing: https://codesandbox.io/s/3wqx67pq6

writing node.js get handler with parameters?

How do I write a get handler for the following URL with node.js?
http://localhost:3000/auth?code=xxxxxxx
The following code did not work
app.get('/auth', function (req,res) {
});
It's not working because it doesn't do anything. You need to send a response:
app.get('/auth', function (req,res) {
res.send('Hi it worked. Code: ' + req.query.code);
});
Another way to do it would be like this:
app.get('/auth/:code', function (req,res) {
res.send('Hi it worked. Code: ' + req.params.code);
});
and the URL would simply be http://localhost:3000/auth/xxxxxxx
Please note that, some client sides should accept a certain response type.
For instance, you should send a JSON object as a response.
So, rather than just responding a string, it is better if you send a JSON object as:
app.get('/auth', function (req,res) {
res.send({ 'response' : 'Hi it worked.', 'code': req.query.code });
});

Resources