Express routing post call unexpected token in json - json

I need some help with my routing in Express and making a post call, and retrieving the data within the postrequest.
I've tried retrieving the data by loging req.body but that returns {}, I tried adding the bodyParser to my App.js which gets me the following error when I make a post call:
POST http://localhost:3000/enquete/test/ 400 (Bad Request)
SyntaxError: Unexpected token # in JSON at position 0
This is my code:
App.js
const express = require('express')
const app = express()
var MongoClient = require('mongodb').MongoClient
, co = require('co')
, assert = require('assert')
, bodyParser = require('body-parser');
var indexRouter = require('./routes/index.js');
var enqueteRouter = require('./routes/enquete.js');
// support parsing of application/json type post data
app.use(bodyParser.json());
//support parsing of application/x-www-form-urlencoded post data
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'pug');
app.use('/', indexRouter);
app.use('/enquete', enqueteRouter);
app.use(express.static(__dirname + '/routes'));
app.use(express.static(__dirname + '/public'));
app.listen(3000, () => console.log('Example app listening on port 3000!'))
routes/enquete.js
const express = require('express')
var router = express.Router()
router.post('/test/', function(req,res,next){
console.log('request:',req.body);
res.send('hello');
})
module.exports = router;
Ajax post call
function save(array){
$.ajax({
type: 'POST',
data: { name: "Test", location: "TestUSA" },
contentType: 'application/json',
url: 'http://localhost:3000/enquete/test/',
success: function(data) {
console.log('success');
console.log(JSON.stringify(data));
},
error: function(error) {
console.log('error:', error)
}
});
}

Can you use Postman to test the route? Make sure to select x-www-form-urlencoded as the body format since you're using bodyparser.urlencoded({ extended: true })

Related

HTML Script cannot get fetch data

I try to get my data from mongoDB then use res to send all content to client side but I keep getting undefined, can anyone help me? Thank yall!!!
//// server.js
app.get('/user/show', userController.userList);
//// controller
const usersList = async (req, res) => {
const users = await User.find({});
const usersStr = JSON.stringify(users);
// tried console.log(userStr), can get correct output
res.json({'users': usersStr});
}
//// HTML Script
async function test() {
const result = fetch('/user/show',{
method: 'GET',
headers: {
'Contect-Type': 'application/json',
}
}).then((response) => response.json());;
console.log(result.messages.);
}
test();
If the data of the client come undefined myabe you dont have body-parser install.
body-parser
npm i body-parser
your index.js
const bodyParser = require('body-parser')
// app by app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true })

Why Does My req.body Return Empty on Express

I can't understand why I'm getting an empty req.body {} in client side I get undefined or when I try to use payload = req.body.payload and console.log(payload) I get undefined on the server side and on the client side I get (chrome developer tool console)
ERROR TypeError: Cannot read properties of null (reading 'payload').
What I don't understand is the server receives the request payload(status 201) the response payload is empty, also correct me if I'm wrong the response is a JavaScript object and in the service the original payload is contained so shouldn't I get that in the response.
I have looked at many topics that have the same issue. I'm already doing things that fixed some of the issues.
I have a Content-Type application/json, I apply the app.use(json()) before I use my routes, which seemed to have been the problem with some. Yet I still get empty re.body. I have tried so many things with no luck. Am I missing something? Code snippet.
I would appreciate a point in the right direction
Thanks In Advance
PH.
service.ts
export interface Products{
_id: string,
name: string
}
#Injectable({
providedIn: 'root'
})
export class SearchService {
constructor(private http:HttpClient) { }
searchProducts(query:string){
console.log("Does it get my searchProducts");
return this.http.post<{payload: Array<Products>}>(productsUrl, {payload: query}, {
headers: new HttpHeaders({'Content-Type': 'application.json'})
}).pipe(
map(data => data.payload)
);
}
}
header.ts
sendData(event:any){
//console.log(event.target.value);
let query:string = event.target.value;
//Will match if query is nothing or only spaces
let matchSpaces:any=query.match(/\s*/);
console.log("What about match");
if(matchSpaces[0] === query){
console.log("What about query");
//.products=[];
console.log("what is in collection", this.products);
this.hasQuery = false;
return;
}
console.log("about to call service")
this.searchService.searchProducts(query.trim()).subscribe((results) =>{
console.log("does it get pass subscribe")
// this.products = results;
this.hasQuery = true;
console.log(results);
})
}
route file getProducts.js
var express = require('express');
const cors = require('cors');
var bodyParser = require('body-parser')
const Products = require('../../../liveSearch');
const { query } = require('express');
var router = express.Router();
const app = express();
router.get('/', function(req, res){
res.send('GET route on api here.');
});
/*router.post('/getproducts', function(req,res){
res.send("Trying to post")
});*/
/*app.use(cors());
var corsOptions = {
origin: 'http://localhost:4200',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}*/
router.post('/getProducts', async(req, res) =>{
let payload=req.body;
//let payload= req.body.payload;
let search = await Products.find({name: {$regex: new RegExp('^'+payload+'.*',
'i')}}).exec();
//Limit search to 10
search = search.slice(0, 10);
console.log("Payload", payload)
//.log("Inside search",search);
res.status(201).json(payload) //added to see why I couldn't get
response
// res.send({payload:search});
})
server.js
const express = require('express');
const cors = require('cors');
const router = express.Router();
var bodyParser = require('body-parser');
const Products = require('./liveSearch');
const getProducts = require('.../../controllers/api/getProducts/getProducts')
//const products = require('.../../routes/products.js')
const mongoose = require('mongoose');
//mongoose.Promise = Promise;
mongoose.connect('mongodb://localhost/productLiveSearch', {useNewUrlParser:
true, useUnifiedTopology: true, });
const db = mongoose.connection;
db.on('error', error => console.log(error));
db.once('open', () =>{ console.log('Connected to Mongoose')});
const app = express();
app.use(function(req,res,next){
res.header('Access-Control-Allow-Origin', '*');
res.header('content-type','application/json');
res.header('Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Methods','POST, GET, DELETE, PUT, OPTIONS');
res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE');
next();
});
app.use(cors());
var corsOptions = {
origin: 'http://localhost:4200',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.use(express.json());
app.use(express.urlencoded({extended:true}));
// app.use(express.json({ limit: "1000mb" }));
// app.use(express.urlencoded({ limit: "1000mb", extended: true }));
app.use('/', getProducts);
app.use('/getProducts', getProducts);
app.get('/', function(req, res){
res.send('hello world');
});
app.listen(process.env.Port|| 3000, () => {
console.log("Server has started on Port 3000");
});

How to receive (and decode) JSON from post data in Node.Js Express?

Suppose I have sent data with the following code:
$.ajax({
type: "POST",
url: "/save/" + #{key},
data: transitions2,
success: function (data) {
},
dataType: "json"
});
where transitions2 is hierarchical JS object.
Now how can I receive it intact at server side
router.post('/save/:key', function(req, res) {
// where is my data here?
});
UPDATE
I found info about body parsers, and found that my site template already contained them. Particularly, app.js contains:
...
var bodyParser = require('body-parser');
...
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/data', express.static(path.join(__dirname, '../data')));
app.use('/', index);
...
So I wrote in my index.js:
...
router.post('/save/:key', function(req, res) {
var transitions = req.body;
image_data.save_transitions(req.params.key, req.query.postfix, transitions);
});
...
Unfortunately, transitions contains
while on client side it contained
i.e. was full of data.
What can be the problem?
UPDATE 2
I tried to do
$.ajax({
type: "POST",
url: "/save/" + #{key},
data: JSON.stringify(transitions2),
success: function (data) {
}
});
and I see in Fiddler2 now, that full Json is passed.
[{"start_image":"20170402_1_NATURAL_COL0R","end_image":"20170409_1_NATURAL_COL0R","transition_classes":["no_transition","some_activity"]},...
Unfortunately, on server side I observe truncated and corrupted string
(equal sign should not be in JSON).
And JSON.parse fails.
use body-parser middleware to retrieve the data.
npm install body-parser
configure this in express app.
Find below the sample code
var bodyParser = require('body-parser');
app.use(bodyParser.json());
Then in your router use the following:
router.post('/save/:key', function(req, res) {
var data = req.body // here is your data
});
The problem was on client side only. Correc way to post complex object with json is:
$.ajax({
type: "POST",
url: "/save/" + #{key},
data: JSON.stringify(transitions2),
contentType: "application/json; charset=utf-8",
success: function (data) {
}
});
stringify and contentType are obligatory.
front:
axios.post('/attack', {
number:number,
count:count
},
{
headers:{contentType: "application/json; charset=utf-8"}
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
}
back:
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
app.use(bodyParser.json())
app.post('/attack', (req, res) => {
let data = req.body
console.log(data)
res.send('200')
})
console log: { number: '(number)', count: '(count)' }

nodeJS - make HTTPS request, sending JSON data

I would like to send an HTTPS POST from one nodeJS server to another. I have some JSON data I would like to send with this request (populated by a html form).
How can I do this? I am aware of https.request() but there does not seem to be an option to include JSON as a part of the query. From my research it seems possible with an HTTP request, but not an HTTPS request. How can I solve this?
const pug = require('pug');
var cloudinary = require('cloudinary');
var express = require('express');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
var request = require('request');
var bodyParser = require('body-parser');
var options = {
hostname: 'ec2-54-202-139-197.us-west-2.compute.amazonaws.com',
port: 443,
path: '/',
method: 'GET'
};
var app = express();
var parser = bodyParser.raw();
app.use(parser);
app.set('view engine', 'pug');
app.get('/', upload.single('avatar'), function(req, res) {
return res.render('index.pug');
});
app.get('/makeRequest*', function(req, res) {
query = req['query'];
/*
Here, I would like to send the contents of the query variable as JSON to the server specified in options.
*/
});
You can send JSON data through a POST http request with the native https node module, as stated in the documentation
All options from http.request() are valid.
So, taking the http.request() example you can do the following:
var postData = querystring.stringify({
'msg' : 'Hello World!'
});
var options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
var req = https.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
// write data to request body
req.write(postData);
req.end();
You should edit postData to your desired JSON object
I believe the below is what you want. Using the request library. See comments in the code for my recommendations.
...
var options = {
hostname: 'ec2-54-202-139-197.us-west-2.compute.amazonaws.com',
port: 443,
path: '/',
method: 'POST',
json: true
};
...
//making a post request and sending up your query is better then putting it in the query string
app.post('/makeRequest', function(req, res) {
var query = req.body['query'];
//NOTE, you cannot use a GET request to send JSON. You'll need to use a POST request.
//(you may need to make changes on your other servers)
options.body = { payload: query };
request(options, function(err, response, body) {
if (err) {
//Handle error
return;
}
if (response.statusCode == 200) {
console.log('contents received');
}
});
});
as matt mentioned you need to use request
to send JSON object not JSON.Stringify so that at the server you can receive it using:
app.post('/makeRequest', function(req, res) {
console.log (req.body.param1);
}
Use the following code:
var request = require("request");
request({
'url':"http://www.url.com",
method: "POST",
json: true,
body: {'param1':'any value'}
}, function (error, resp, body) {
console.log ("check response.");
});

POST request through a JSON object

I have created a server which serves the post request for a client. I am using the bodyserver, but getting some error
var bodyParser = require('body-parser')
var express = require('express');
var app = express();
app.use(bodyParser.json());
app.post('/v3/botstate/:channel/users/:userid', function (req, res) {
console.log("hsijdaf");
console.log(req.body);
//console.log(req.body);
// res.send('Hello POST');
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
A client is as shown below,
var request = require('request');
request.post({
url: "http://localhost:8081/v3/botstate/webchat/users/siddiq",
headers: {
"Content-Type": "application/json"
},
body: '{"jsonrpc":"2.0","id":"zdoLXrB5IkwQzwV2wBoj","method":"barrister-idl","params":[]}',
json:true
}, function(error, response, body){
console.log(error);
console.log(JSON.stringify(response));
console.log(body);
});
while running the client getting the below error,
E:\TESTING>node exp.js
Example app listening at http://:::8081
SyntaxError: Unexpected token "
at parse (E:\TESTING\node_modules\body-parser\lib\types\json.js:83:15)
at E:\TESTING\node_modules\body-parser\lib\read.js:116:18
at invokeCallback (E:\TESTING\node_modules\body-parser\node_modules\raw-body\index.js:262:16)
at done (E:\TESTING\node_modules\body-parser\node_modules\raw-body\index.js:251:7)
at IncomingMessage.onEnd (E:\TESTING\node_modules\body-parser\node_modules\raw-body\index.js:307:7)
at emitNone (events.js:67:13)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:921:12)
at nextTickCallbackWith2Args (node.js:442:9)
at process._tickCallback (node.js:356:17)
please help me in resolving the issue.
You have set Content-Type : application/json in your client, but your POST data is text/plain, not json. That's why body-parser is failing to parse it as it was expecting json through header.
Try after removing ' ' from body in your client.
e.g.
var request = require('request');
request.post({
url: "http://localhost:8081/v3/botstate/webchat/users/siddiq",
headers: {
"Content-Type": "application/json"
},
body: {
"jsonrpc":"2.0",
"id":"zdoLXrB5IkwQzwV2wBoj",
"method":"barrister-idl",
"params":[]
},
json:true
}, function(error, response, body){
console.log(error);
console.log(JSON.stringify(response));
console.log(body);
});
Hope it helps you.