Request body is empty in Post - javascript

The following is a test file written with reference to my previous question:model.save() returns an invalid output
.
// Imports
var express=require("express")
, mongoose=require("mongoose")
, bodyParser= require('body-parser')
, bodyParser = require("body-parser");
const { Int32 } = require("bson");
// Constants
const app = express()
const PORT=4002
// Create a model
const dataModel=mongoose.model('dataCollection',mongoose.Schema(data))
// Our Schema
var data={
value: Number
}
// Making connection with database
mongoose.Promise= global.Promise;
mongoose.connect('mongodb://localhost/testdb', {
useNewUrlParser:true,
useUnifiedTopology:true
})
// Create the controller to save data
function postData(req,res){
console.log(req.body)
let newData = new dataModel(req.body)
newData.save((err,resp)=>{
if(err) console.log(err)
else res.json(resp)
})
}
// express set root page
app.get('/',(req,res)=> res.send("ROOT PAGE"));
// Set Route for our post request
app.route('/app')
.get((req,res)=>res.send("Nothing here"))
.post(postData);
// body-parser setup
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
// start listening on server
app.listen(PORT,()=>console.log(`Your application is running on Port: ${PORT}`));
The above code prints undefined for console.log(req.body) in controller function postData for the POST request shown here:

You can imagine the request is coming from the top and goes to the bottom.
It does not make sense to parse the body after you visited the route. You need to parse the body first and THEN visit the route.
// body-parser setup
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
// express set root page
app.get('/',(req,res)=> res.send("ROOT PAGE"));
// Set Route for our post request
app.route('/app')
.get((req,res)=>res.send("Nothing here"))
.post(postData);
However bodyparsers isnt used anymore. You can use instead app.use(express.json())

Related

Cannot parse the string in the POST request in Express Js

I want to create a simple API with a post method in which the string will be sent as a request.On debugging I found that that the string could not be parsed on logging it was showing undefined
I have tried app.use(express.json());
Also tried middleware functions but it didn't work.
INDEX.JS
const express = require('express');
const env = require('dotenv');
const bodyParser = require('body-parser');
//importing the express module
const app = express();
//creating the app
env.config();
app.use(bodyParser());
//get request for the first page which is set to be a default
app.get('/',(req,res,next)=>{
res.send('welcome to the first page');
console.log(`welcome to the ecommerce site which is oon the ip and port np ${process.env.PORT }`);
});
app.post('/data',(request,response,next)=>{
response.status(200).json({message:request.body});
console.log(response.body);
})
//creating an which listens on port 4000
app.listen(process.env.PORT,()=>{
console.log(`application running at the port ${process.env.PORT}`);
});
on posting XYZ or 'XYZ ' or "XYZ" it is printing at localhost:4000/data
{
"message": {}
}

returning undefined for get request

I have been doing a project in URL shortening and i am getting an undefined as a result to get request.
Also i get a blank page too as result,but according to my knowledge everything is ok,i can't figure out what is the mistake
Here's my code(please check the app.get section)
'use strict';
var bodyParser = require('body-parser')
var express = require('express');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var http = require("http");
var cors = require('cors');
const dns = require('dns');
var app = express();
// Basic Configuration
var port = process.env.PORT || 3000;
/** this project needs a db !! **/
// mongoose.connect(process.env.DB_URI);
app.use(cors());
/** this project needs to parse POST bodies **/
// you should mount the body-parser here
app.use('/public', express.static(process.cwd() + '/public'));
app.get('/', function(req, res){
res.sendFile(process.cwd() + '/views/index.html');
});
// your first API endpoint...
app.get("/api/hello", function (req, res) {
res.json({greeting: 'hello API'});
});
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
var saveSchema = new mongoose.Schema({
name: String,
url: Number,
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
/** 3) Create and Save a Person */
var SaveData = mongoose.model('Save', saveSchema);
//**Here's the start of my problem,i think**
app.get("/api/shorturl/:id1",function(req,res){
SaveData.find({url:1},function(err,data){ console.log(data.name)//**i am getting undefined for this in console**
res.json(data.name);})
});
app.post("/api/shorturl/new",(req,res)=>{
var body=req.body.url;
dns.lookup(body,(err,data)=>{
var new2= new SaveData({name:body,url:1});
new2.save((err,data)=>{res.json(new2);});
})
});
app.listen(port, function () {
console.log('Node.js listening ...');
});
I checked my DB whether the schema data is inputted or not, it is getting inside DB, so retrieval makes the problem I think.
mongoose.model.prototype.find returns an array of objects found. If you type Array.prototype.name in a console somewhere, you'll get undefined. Instead, use mongoose.model.prototype.findOne.
Your enviorment variables are working? I notice you're not using dotenv module or something like that to configure your process.env.

.save() hanging and only receiving _id

problem with saving to MongoDB database
This is my second time trying to post to a database, still new to it. I am receiving string from a html form and trying to save into the database. I have connected to mongodb successfully, setup my post route, setup my model and now trying to send the http request to save it to db. before setting up the model, I was able to console.log the data I received from my form. but after setting up the model and trying to get the route to save it to db, it just hangs. If i comment out the main.save(), and console.log(main), alll I get back is an _id.
i cant figure out where im going wrong with it
index.js
const express = require('express')
const path = require('path')
const routes = require('../routes/routes')
const app = express()
const port = 3000
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(express.static(path.join(__dirname, '../public')))
app.use(routes)
app.listen(port, () => {
console.log('Server is up on port ' + port)
})
routes
const express = require('express')
const Main = require('../src/model')
const router = new express.Router()
router.post('/', async (req, res) => {
const main = new Main(req.body)
console.log(main)
try{
await main.save()
res.status(201).send(main)
} catch (e) {
res.status(400).send(e)
console.log('Not working!')
}
})
module.exports = router
model
const mongoose = require('mongoose')
const Main = mongoose.model('Main', {
total_check: {
type: String
}
})
module.exports = Main
receiving an _id, but hanging on .save()
This is because you are passing whole req.body to the database. Change this const main = new Main(req.body) to this
let main= new Main({
total_check:req.body.total_check
});
Just make sure you are receiving correct data from your frontend end or Postman.
Also save returns a callback so handle that as well
main.save((err,main)=>{
if(err) {console.log(err) }
else { res.status(201).send(main) }
});

How to use Express middleware functions correctly in router?

In this example below, you can see that the csrfProtection and parseForm functions are passed as parameters/callbacks in the GET and POST requests...
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express()
// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())
app.get('/form', csrfProtection, function(req, res) { // HERE
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', parseForm, csrfProtection, function(req, res) { // AND HERE
res.send('data is being processed')
})
However, if you are using a router, like I am, how can use these same functions? I am aware that by "using" them in app.js, they are made available on the req object but in the example given above, they are required as the 2nd and 2nd & 3rd arguments of the GET and POST routes, but req isn't made available until you're inside the final callback?!
So I know you can't do the below (just as an example)... so how should you use them? Would I have to re-declare them in every routes file?
Separate routes file: routes/someroute.js
...
router
.post('/', req.body, req.csrfProtection, (req, res) => {
})
...
Thanks in advance :)
Reference: https://www.npmjs.com/package/csurf
UPDATE
Following comments below, I have made the following changes to my app.js file.
app.js
...
global.bodyParser = require('body-parser').urlencoded({extended: false});
app.use(global.bodyParser);
global.csrfProtection = csrf({ cookie: false });
...
routes/myroute.js
router
.post('/', global.bodyParser, global.csrfProtection, (req, res) => {})
However, when I restart the server I am seeing this error, which suggests that that the global function is not defined... what am I missing here? :-/
Error: Route.post() requires a callback function but got a [object Undefined]
I think you ask about sharing middlewares across all API/routes files
You can do it like this :
First in your main file lets call it server.js we use you're code
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// create express app
var app = express()
// setup route middlewares
app.use(bodyParser.urlencoded({ extended: false }))
// parse cookies
app.use(cookieParser())
//enable your JS API/route script.
const awesomeAPI = require('./awesomeApi.js');
app.use('/awesome', awesomeAPI );
app.listen(3000);
Now you have file let's calle it awesomeApi.js
const express = require('express');
const awesomeApi = express.Router();
awesomeApi.route('/')
.post(req,res => {
//req.body present here. And body parser middle ware works.
})
module.exports = awesomeApi;
Hope this helps.
Some links:
https://expressjs.com/en/guide/using-middleware.html
https://expressjs.com/en/4x/api.html#express

Express body-parser: req.body returns empty object

I've got a simple Express server that uses the body-parser module to access POST-parameters. The app looks like this:
/index.js:
'use strict';
const express = require('express');
const app = express();
const apiRouter = require('./api/routes.js');
// Set our port for the server application
const port = process.env.PORT || 8080;
// Register the routes for the /api prefix
app.use('/api', apiRouter);
// Start server
app.listen(port);
console.log('The server is running on port ' + port);
/api/routes.js:
'use strict';
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
// Configure app to use bodyParser(). This will let us get the data from a POST
router.use(bodyParser.urlencoded({ extended: true }));
router.use(bodyParser.json());
// START ROUTES
router.post('/devices', (req, res) => {
console.log(req.body); // Returns {}
res.json(req.body);
});
module.exports = router;
The problem is that the req.body object is empty (Always returns an empty object {}). Since I already loaded the body-parser middleware I have no idea what else I can try. I hope you have any suggestions.
I used the app Postman for testing. It appeared that it sent the POST data as form-data instead of x-www-form-urlencoded. After changing this setting the data showed up.

Categories