Getting POST parameters not working - javascript

I'm trying to send a post parameter (key: test, value: somevlaue) using PostMan using restify framework. For this I've used 2 methods and both are not working:
1st one shows this error:
{
"code": "InternalError",
"message": "Cannot read property 'test' of undefined"
}
2nd one (commented) shows only Error: someerror
Am I doing something wrong?
Here's my code:
var restify=require('restify');
var fs=require('fs');
var qs = require('querystring');
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false })
var controllers = {};
var server=restify.createServer();
server.post("/get", function(req, res, next){
res.send({value: req.body.test,
error: "someerror"});
//**********METHOD TWO*********************
/*
if (req.method == 'POST') {
var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end', function () {
var post = qs.parse(body);
res.send({
Data: post.test,
Error: "Someerror"
});
});
}
*/
});
server.listen(8081, function (err) {
if (err)
console.error(err);
else
console.log('App is ready at : ' + 8081);
});

With restify ^7.7.0, you don't have to require('body-parser') any more. Just use restify.plugins.bodyParser():
var server = restify.createServer()
server.listen(port, () => console.log(`${server.name} listening ${server.url}`))
server.use(restify.plugins.bodyParser()) // can parse Content-type: 'application/x-www-form-urlencoded'
server.post('/your_url', your_handler_func)

It looks like you might have your bodyparser set up incorrectly.
According to the docs under the body parser section you set up the parser in this manner:
server.use(restify.bodyParser({
maxBodySize: 0,
mapParams: true,
mapFiles: false,
.....
}));
The default is to map the data to req.params but you can change this and map it to req.body by setting the mapParams option to false
BodyParser
Blocks your chain on reading and parsing the HTTP request body.
Switches on Content-Type and does the appropriate logic.
application/json, application/x-www-form-urlencoded and
multipart/form-data are currently supported.

Related

When using a fetch request in a Node JS server it receives the body as blank

I was working on a user login system in Node JS and was making a POST request to the server like this.
let data = {
username: "John Doe",
password: "123abc",
}
let options = {
method: 'POST',
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(data),
}
fetch('/verify-login', options).then(function(r) {
return r.text();
}).then(function(dat) {
if (dat == 'n') {
document.getElementById('login-fail').innerHTML = 'User name or password is incorrect!';
} else {
console.log('Login Success');
}
});
Server Side code:
const express = require('express');
const port = 80;
const bodyParser = require("body-parser");
const fs = require('fs');
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
const cors = require("cors");
app.use(cors());
app.post('/verify-login', async function(q, r) {
let dat = await q.body; //<-- Body is just {} not what the fetch request sent
//do account check stuff with dat
if (success) {
r.send('y');
} else {
r.send('n');
}
});
app.listen(port, function() {
console.log("Started application on port %d", port);
});
This issue is that on the server side when I receive the request, the body is returned with '{}'. Does anybody know why this is happening and how I can fix it?
There are various data types you can pass to fetch through the body option.
If you pass something it doesn't recognise, it converts it to a string and sends that.
Converting a plain object to a string doesn't give you anything useful.
let data = {
username: "John Doe",
password: "123abc",
}
console.log(`${data}`);
You said you were sending JSON (with the Content-Type header. So you need to actually send JSON.
const json = JSON.stringify(data);

How to send input field value to Node JS backend via AJAX call for typeahead functionality

I am trying to implement a typeahead functionality as below.
html page
...
...
<input id="product" name="product" type="text" class="form-control" placeholder="Enter Product Name" autocomplete="off">
...
...
<script>
$(document).ready(function () {
fetchTypeAheadResult();
});
function fetchTypeAheadResult() {
$('#product').typeahead({
source: function (request, response) {
var formData = {
'product' : $('#product').val()
}
// var formData = $('form').serialize();
$.ajax({
url: "/search",
dataType: "json",
type: "POST",
data: formData,
contentType: "application/json; charset=utf-8",
success: function (result) {
var items = [];
response($.map(result, function (item) {
items.push(item.name);
}))
response(items);
// SET THE WIDTH AND HEIGHT OF UI AS "auto" ALONG WITH FONT.
// YOU CAN CUSTOMIZE ITS PROPERTIES.
$(".dropdown-menu").css("width", "100%");
$(".dropdown-menu").css("height", "auto");
$(".dropdown-menu").css("font", "12px Verdana");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
hint: true, // SHOW HINT (DEFAULT IS "true").
highlight: true, // HIGHLIGHT (SET <strong> or <b> BOLD). DEFAULT IS "true".
minLength: 1 // MINIMUM 1 CHARACTER TO START WITH.
});
}
</script>
...
...
And my back end node js code is as following
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const app = express();
// configure the app to use bodyParser() to extract body from request.
app.use(bodyParser.urlencoded({ extended: true }));
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }));
app.post('/search', (req, res) => {
let searchText = req.body;
console.log('Search string >> ' + req);
console.log('Search string >> ' + JSON.stringify(req.body));
console.log('Search string >> ' + req.body.product);
// Not correct, but still trying if it works
// var result = triestrct.get(req.body.product);
res.send({test:'text'}); // TODO - to be updated with correct json
});
Now whenever I am trying to type on the "product" text field, it is invoking the back end /search api. However, I am unable to capture the value of product field.
Any help will be appreciated ? Note, I need typeahed functionality with ajax call to send input text value to back end.
Output of the three consol logs as following...
Search string >> [object Object]
Search string >> {}
Search string >> undefined
express doesn't parse the input provided to API by it self. Thus we need some additional tool like body-parser to fetch input from request and format it into JSON. This can be done without body-parser too.
Do go through this documentation it covers a lot.
Using body-parser, you need to setup body-parser with express:
```
const bodyParser = require('body-parser'),
// For Cross-Origin Resource Sharing
CORS = require('cors'),
express = require('express');
const app = express();
// Cross-Origin Resource Sharing
app.use(CORS());
// configure the app to use bodyParser() to extract body from request.
// parse urlencoded types to JSON
app.use(bodyParser.urlencoded({
extended: true
}));
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }));
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }));
// This will get you input at `req.body`
app.post('/search',(req,res)=>{
console.log(JSON.stringify(req.body));
});
```
Without using body-parser:
```
app.post('/', (req, res, next) => {
let body = [];
req.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
// Without parsing data it's present in chunks.
body.push(chunk);
}).on('end', () => {
// Finally converting data into readable form
body = Buffer.concat(body).toString();
console.log(body);
// Setting input back into request, just same what body-parser do.
req.body = body;
next();
});
}, (req, res) => {
console.log(req.body);
});
```
req.body.product not req.query.product
IN POST verb use body-parser midlleware
const bodyParser = requier('body-parser');
const express = require('express');
const app = new express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.post('/search',(req,res)=>{
console.log(JSON.stringify(req.body));
});
I did not use typeahead before but this example is clear.

Getting cannot POST / error in Express

I have a RESTful API that I am using postman to make a call to my route /websites. Whenever I make the call, postman says "Cannot POST /websites". I am trying to implement a job queue and I'm using Express, Kue(Redis) and MongoDB.
Here is my routes file:
'use strict';
module.exports = function(app) {
// Create a new website
const websites = require('./controllers/website.controller.js');
app.post('/websites', function(req, res) {
const content = req.body;
websites.create(content, (err) => {
if (err) {
return res.json({
error: err,
success: false,
message: 'Could not create content',
});
} else {
return res.json({
error: null,
success: true,
message: 'Created a website!', content
});
}
})
});
}
Here is the server file:
const express = require('express');
const bodyParser = require('body-parser');
const kue = require('kue');
const websites = require('./app/routes/website.routes.js')
kue.app.listen(3000);
var app = express();
const redis = require('redis');
const client = redis.createClient();
client.on('connect', () =>{
console.log('Redis connection established');
})
app.use('/websites', websites);
I've never used Express and I have no idea what is going on here. Any amount of help would be great!!
Thank you!
The problem is how you are using the app.use and the app.post. You have.
app.use('/websites', websites);
And inside websites you have:
app.post('/websites', function....
So to reach that code you need to make a post to localhost:3000/websites/websites. What you need to do is simply remove the /websites from your routes.
//to reach here post to localhost:3000/websites
app.post('/' , function(req, res) {
});

Append objects to a json file

I have a task to implement a pseudo cart page and when I click on checkout i want to send a request to a json file "ordersTest.json" with a following structure:
{ "orders": [] }. So when a post request is sent i have to put the data in that orders array in the json. I am completely new to Nodejs and express. This is my first project on it and i came up with a very simple server.
const express = require('express')
const path = require('path')
const fs = require('fs')
const url = require('url')
const bodyParser = require('body-parser')
const app = express()
const ordersJson = require('./public/ordersTest.json');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.post('/api/orders', (req, res) => {
let body = req.body;
console.log(body);
fs.appendFile('./public/ordersTest.json', JSON.stringify(body), err => {
if (err) console.log(err);
})
})
But this thing only appends it to the end of the file. I need to put it inside this orders array
This is my ajax passing an example object in the body of the post:
$(".btn-checkout").on('click', function() {
let date = new Date();
$.ajax({
method : "POST",
url: "/api/orders",
data : {a: "abc"},//{ order: "order",date: date.toDateString(), order: JSON.stringify(cart)},
success : function(success){
console.log(success,'success');
},
error : function(err) {
console.log(err);
}
});
clearCart();
displayClearedCart();
});
You need to parse the JSON file and then treat it like an object. Once you are done with it, convert it to JSON again and overwrite your file. like this
app.post('/api/orders', (req, res) => {
let body = req.body;
var ordersTest = require('./public/ordersTest.json');
ordersTest.orders.push(body);
fs.writeFile('./public/ordersTest.json', JSON.stringify(ordersTest), function(err) {
if (err) res.sendStatus(500)
res.sendStatus(200);
});
})
Not tested, please fix typo error if any.

node.js / jQuery cross domain: ERR_CONNECTION_REFUSED

I'm new to Node.js.
I'm creating a simple node/express application that serves a single web page containing one button that when clicked makes a jQuery ajax request to an Express route.
The route callback makes an http.get request to openexchangerates.org for some json data containing foreign exchange rates. The JSON is then output to the Developer Tools console window.
The application works on the first button click, but on any subsequent clicks the console window displays:
GET http://127.0.0.1:3000/getFx net::ERR_CONNECTION_REFUSED
A screen grab of the Developer Tools console window shows the result of the first click, and then the second click when the connection is refused.
The error detail is as follows:
GET http://127.0.0.1:3000/getFx net::ERR_CONNECTION_REFUSED jquery-2.1.3.min.js:4
n.ajaxTransport.k.cors.a.crossDomain.send jquery-2.1.3.min.js:4
n.extend.ajax (index):18
(anonymous function) jquery-2.1.3.min.js:3
n.event.dispatch jquery-2.1.3.min.js:3
n.event.add.r.handle
My simple Node/Express application is as follows:
var express = require('express');
var app = express();
var http = require("http");
var data = "";
var json;
console.log( "__dirname", __dirname );
app.use( express.static( __dirname + '/') );
var options = {
host:"openexchangerates.org",
path:"/api/latest.json?app_id=<get free ID from openexchangerates.org>"
};
app.get("/", function( req, res ) {
res.sendFile('index.html', { root: __dirname });
})
app.get("/getfx", function(req, res) {
console.log("Route: getFx");
getFx(res);
})
function getFx(res) {
console.log("http getFx");
http.get(options, function (response) {
response.on("data", function (chunk) {
//console.log("data:\n"+chunk);
data += chunk;
});
response.on("end", function () {
json = JSON.parse(data);
console.log("http response end:");
res.end( data );
});
response.on("error", function (e) {
console.log("error:\n" + e.message);
});
})
}
app.listen(3000);
My html index page is:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Get FX</title>
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script>
$(document).ready(function() {
console.log( "document ready");
$("#btnFx").click(function() {
console.log('clicked', this );
$.ajax({
url : "http://127.0.0.1:3000/getFx",
dataType : "json",
success : function(json) {
console.log("json returned:\n", json);
}
});
} );
})
</script>
</head>
<body>
<button id="btnFx" style="width:200px">Get foreign exchange rates</button>
</body>
For openexchangerates.org to serve the data, a free app id is required. Anyone able to help resolve this may have to go through their very short sign up:
That link is here:
https://openexchangerates.org/signup/free
However it's possible that my mistake is glowingly obvious to those with better Node/Express/jQuery knowledge.
Many thanks in advance
The way you defined your data and json vars is causing subsequent requests to fail. Since you defined them up front, all requests will re-use them, meaning by the time you JSON.parse data for the second request, data will contain two valid json strings, thus making one invalid json string. To fix this, define data and json farther down in the callback.
var express = require('express');
var app = express();
var http = require("http");
//var data = "";
//var json;
console.log( "__dirname", __dirname );
app.use( express.static( __dirname + '/') );
var options = {
host:"openexchangerates.org",
path:"/api/latest.json?app_id=<get free ID from openexchangerates.org>"
};
app.get("/", function( req, res ) {
res.sendFile('index.html', { root: __dirname });
})
app.get("/getfx", function(req, res) {
console.log("Route: getFx");
getFx(res);
})
function getFx(res) {
console.log("http getFx");
http.get(options, function (response) {
var data = "";
var json;
response.on("data", function (chunk) {
//console.log("data:\n"+chunk);
data += chunk;
});
response.on("end", function () {
console.log("http response end:");
json = JSON.parse(data);
res.json(json);
});
response.on("error", function (e) {
console.log("error:\n" + e.message);
});
})
}
app.listen(3000);
Issue comes from Cross origin requests protection which happens on localhost with chrome. Try to use other browser or just Allow origin to all hosts (*) or your host (http://localhost:3000):
app.use( express.static( __dirname + '/') );
app.use(function(req,res,next){
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
// intercept OPTIONS method
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
});

Categories