i have installed body parser through npm, required it, set it with express buti am still getting req.body undefined. If someone knows whats wrong please let me know i feel like its something stupid im missing.
This is my app.js file
const express = require('express')
const index = require('./routes/index');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
//Create the express server
const app = express();
// Use index routes file
app.use('', index);
// Use the /public folder for our assets
app.use('/public', express.static('public'));
// Use body-parser and cookie-parser
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(cookieParser);
// Set ejs as our templating engine
app.set('view engine', 'ejs');
// Catch 404 and forward to error handler
app.use(function(req, res, next) {
const err = new Error('Not Found');
err.status = 404;
next(err);
});
// Error handler
app.use((err, req, res, next) => {
res.locals.message = err.message;
res.status(res.statusCode || 500);
res.render('error', {error: err.message});
console.log(err.message);
});
app.listen(process.env.PORT || 3000, () => {
console.log('Application running on localhost:3000');
});
This is my route index.js file that's making the post
const express = require('express');
const router = express.Router();
const fs = require('fs');
const movie_controller = require('../controllers/movieController');
const bodyParser = require('body-parser');
const request = require('request');
router.get('/about', (req, res, error) => {
res.render('about');
});
router.get('/', movie_controller.get_index);
router.get('/currently_playing', movie_controller.get_currently_playing);
router.get('/top_rated', movie_controller.get_top_rated);
router.get('/upcoming', movie_controller.get_upcoming);
router.get('/movie_view/:id', movie_controller.get_movie);
// Post request for a search query
router.post('/search', (req, res, next) => {
console.log('Query', req.body);
// Make request for query
request('https://api.themoviedb.org/3/search/movie?api_key=&language=en-
US&query=' + req.body + '&page=1&include_adult=false', (error, response,
body) => {
//handle errors
if(error){res.render('error', {error: error.message})}
//handle body
if(response.statusCode === 200){
//place body data in a variable for later reference
let movieData = JSON.parse(body);
let movies = [];
movieData.results.forEach(movie => {
movies.push(movie);
});
// Make request for genres
request('https://api.themoviedb.org/3/genre/movie/list?
api_key=&language=en-US', (error, response, body) => {
//handle errors
if(error){res.render('error', {error: error.message})}
//handle body
if(response.statusCode === 200){
//place body in a variable for later reference
let genreData = JSON.parse(body);
let genres = [];
genreData.genres.forEach(genre => {
genres.push(genre);
});
res.render('results', {movie: movies, genres: genres });
}
})
}
})
});
module.exports = router;
This is where the form is on a header.ejs partial
<form class="form-inline my-2 my-lg-0" action="/search" method="post">
<input class="form-control mr-sm-2" type="search" placeholder="Search" name="searchQuery" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>enter code here
You should to use the bodyParser() before app.use('', index) of your router, to avoid any problem just place app.use('', index) it in the last.
// Use body-parser and cookie-parser
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(cookieParser);
// Use index routes file
app.use('', index);
Express middleware runs in the order you register them (routes included). You have registered the bodyParser and cookieParser middlewares after attaching your routes. Therefore, you will not have the parsed body or cookies by the time your route is encountered.
To fix this, make sure that any middlewares you want to run before your actual route are registered before:
const express = require('express')
const index = require('./routes/index');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
//Create the express server
const app = express();
// Use the /public folder for our assets
app.use('/public', express.static('public'));
// Use body-parser and cookie-parser
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(cookieParser);
// Use index routes file
app.use('', index);
...
Related
my database in mongoDb is connected to my nodeJS i can read it there my nodeJs api is connected to my client-side (in reactJS) and i can send data from my nodeJs api using express-generator to my client-side and is working but when i tried to send my mongoDb database to the client-side is not working( but i'm still getting status 200 but my array is not here . I can't figure out why? i cant see the db when i call the api in postman so i assume the error is in the server-side . If i had a consol.log i can see the db but when i use return it is not working and i cant see the data in postman
here my nodeJs code:
var mongodb = require('mongodb')
var MongoClient = mongodb.MongoClient
var connectionURL = 'mongodb://127.0.0.1:27017'
var databaseName = 'projet_Ecommerce';
const dataFromDb = () => {
MongoClient.connect(connectionURL, {
useNewUrlParser: true
}, (error, client) => {
if (error) {
return console.log('Unable to connect to database')
}
console.log('Connected correctly !');
var db = client.db(databaseName)
db.collection('product').find().toArray(function(error, data) {
if (error) {
return console.log('Unable to find the user')
}
return (data);
})
// Pointer - go to doc
// db.collection('tasks').find({completed: false}).toArray()
})
};
module.exports = dataFromDb
routres / index.js:
var express = require('express');
var router = express.Router();
const bodyParser = require('body-parser')
var dataC = require('../public/javascripts/dataFromDb')
// data = JSON.stringify(data);
// console.log(dataFromDb())
/* GET home page. */
router.get('/', function(req, res, next) {
//console.log(dataFromDb())
res.send(dataC())
});
//console.log(dataFromDb())
module.exports = router;
app.js:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require("cors")
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var testAPIRouter = require("./routes/testAPI");
var app = express();
var bodyParser = require("body-parser")
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
// app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use("/testAPI", testAPIRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
other files no change
I'm working on a project that uses ReactJS typescript for the front-end, express for the back-end, and MongoDB for the database.
The main issue I am having is that I want to somehow send data from my React component to the express app so that it can query and add things to the database.
Currently, I have the express server running on http://localhost:9000, and the React app on http://localhost:3000, and I can connect them using routes.
My express app looks like the following:
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var testAPIRouter = require('./routes/testAPI');
var testAddUser = require('./routes/addUser');
const MongoClient = require('mongodb').MongoClient;
const mongoose = require('mongoose');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use("/testAPI", testAPIRouter);
app.use("/addUser", testAddUser);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
const dbRoute = 'mongodb+srv://Adminname:fjfeinjd#pawornaw-b4vzg.gcp.mongodb.net/test?retryWrites=true&w=majority';
mongoose.connect(dbRoute,
{useNewUrlParser: true})
.then(() => console.log("Connected to MongoDB"))
.catch(err => console.error("Could not connected to Mongo"));
module.exports = app;
and my React Component is this, minus import statements. The render function only contains a button that has an onlclick that executes doThing()
constructor(props: any) {
super(props);
this.state = {
showHomePage: true,
showAnimalUploadSearch: false,
showProfile: false,
showAnimal: true,
apiResponse: "",
fName: "bob"
};
this.changeView = this.changeView.bind(this);
// this.callAPI = this.callAPI.bind(this);
// this.componentWillMount = this.componentWillMount.bind(this);
this.doThing = this.doThing.bind(this);
}
callAPI() {
fetch("http://localhost:9000/testAPI")
.then(res => res.text())
.then(res => this.setState({apiResponse: res}))
.catch(err => err);
}
componentWillMount(): void {
this.callAPI();
}
changeView() {
this.setState({showHomePage: !this.state.showHomePage});
this.setState({showAnimalUploadSearch: !this.state.showAnimalUploadSearch});
this.setState({showAnimal: true});
this.setState({showProfile: false});
}
doThing() {
Axios.post('http://localhost:9000/testAPI', ({firstName: this.state.fName}))
.then(res => console.log(res));
}
and finally, testAPI.js looks like this
const router = express.Router();
const axios = require('axios');
router.get('/', function(req, res, next) {
//res.send('API is working properly');
axios.get('http://localhost:3000')
.then(res => console.log("got it"))
.catch(err => err);
});
module.exports = router;
I want to be able to access and use the data that is sent from my react component so that I can query my database with user input in the future. The API does connect with my React code, and when the testAPI function only contains these lines:
const router = express.Router();
const axios = require('axios');
router.get('/', function(req, res, next) {
res.send('API is working properly');
});
module.exports = router;
the message can be displayed on my react app in the browser via the state.
If anyone could help me see what I am doing wrong, or maybe give me a clue as to what other options I can try, please let me know.
Thank you.
When you send post request from client side, it will be in body property of req object
const router = express.Router();
// you shoud listen post request
router.post('/', function(req, res) {
const { body } = req;
// do somethin with data which you recieved in body, save to database for example
// and send response to the client
res.json({ message: 'your data was saved'});
});
module.exports = router;
to send data to client use:
router.get('/', function(req, res) {
res.json({ data: 'Some data'}); // or res.send('some text') to send plain text
});
So I am scraping a website, and I want it to show the data to innerHTML, and I am having trouble getting it to work. I am trying to use
document.getElementById('results').innerHTML = searchJobs('');
But it's telling me that document is not defined, sorry nooby question but It's easier to ask than be stuck on the same thing for 45 minutes.
Here is the code :
function searchJobs(i) {
const url = axios.get('actualurl')
return fetch(`${url}${i}`)
.then(response => response.text())
.then(res => {
const jobs = [];
const jobsBody = [];
const $ = cheerio.load(res.data);
$('.result').each((index, element) => {
const title = $(element).children('.title').text();
const linkToJob = $(element).children('.title').children('a').attr('href')
const body = $(element).children('.summary').text();
jobs[index] = { title, linkToJob, body };
});
return jobs;
});
}
document.getElementById('results').innerHTML = searchJobs('');
module.exports = searchJobs;
I can get the scraper to console.log just fine.
index route :
const express = require('express');
const router = express.Router();
const scraper = require('../scrapers/scrapers');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
app.js :
const express = require('express'),
path = require('path'),
cookieParser = require('cookie-parser'),
logger = require('morgan'),
puppeteer = require('puppeteer'),
axios = require('axios'),
cheerio = require('cheerio');
es6Renderer = require('express-es6-template-engine');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.engine('html', es6Renderer);
app.set('views', './views');
app.set('view engine', 'html');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
I think the problem is actually in the view which it's basically just this to keep the post short :
<body>
<p id="results"></p>
<script src="/scrapers/scrapers.js" async defer></script>
</body>
I think I understand what you're trying to accomplish. Remove the document.getElementById line from scrapers.js and modify the others like so:
index route:
router.get('/', function(req, res, next) {
res.render('index', { locals: { results: scraper.searchJobs() }});
});
view:
<body>
<p id="results">${results}</p>
</body>
By doing this you're running the scraper on the server inside of node and then using the templating engine to render the results into the HTML prior to sending it down to the browser.
I have added body-parser to my application app.js file. I have a routes folder and a controllers folder which handles my request.
Initially, I did not have body-parser added to my application. When I added body-parser and console logged req.body I got an empty object. When I console logged req.body.email, req.body.password, and req.body.displayName values from postman were read as undefined.
app.js
let createError = require('http-errors');
let express = require('express');
let path = require('path');
let cookieParser = require('cookie-parser');
let logger = require('morgan');
let bodyParser = require('body-parser');
let assert = require('assert');
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config()
}
let usersRouter = require('./routes/user');
let app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/user', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
// MongoDB Connection
const db = {};
const MongoClient = require('mongodb').MongoClient;
MongoClient.connect(process.env.MONGODB_CONNECT_URL, (err, client) => {
// Connection works dont worry about it
});
module.exports = app;
routes/user.js
const express = require('express');
const router = express.Router();
const user = require('../controllers/user');
router.post('/', user.createUser);
router.delete('/:id', user.deleteUser);
router.get('/:id', user.loginUser);
module.exports = router;
controllers/user.js
const bcrypt = require('bcryptjs');
const Joi = require('joi');
const ObjectId = require('mongodb').ObjectID;
exports.createUser = async (req, res, next) => {
console.log('Request body: ', req.body);
const email = req.body.email;
const password = req.body.password;
const displayName = req.body.displayName;
console.log('Email: ', email);
console.log('Password: ', password);
console.log('Display name: ', displayName);
};
Please make sure that you are adding content-type header in postman content-type : application/json also in body tab select raw and beside raw select json from drop-down list.
Check this
https://i.stack.imgur.com/ZDhcl.png
You are probably trying to send form-data with Postman which sends a multipar body, body parser cannot handle multipart bodies. For handling multipart bodies you have to use a different module, I normally use multer.
With multer installed you just have to include it and it as middleware (under you body-parser for instance) using none() since in this case you want to handle text-only multipart body (More information about this in multer docs
let multer = require('multer');
app.use(multer().none());
Besides that I wanted to mention you are including two body parsers in your code, the express body parser
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
and an external body-parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
Pick one, you don't need both, the best option for me would be to keep the one that comes with express, this way you don't have to install any more external packages.
I'm learning about REST with node.
I'm trying to use post to add an element to my db.
My code:
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var AdModule = require('../models/ad');
router.route('/')
.get((req, res) => {
AdModule.find((err, col) => {
if (err)
res.send(err);
res.json(col);
})
})
.post((req, res) => {
var ad = new AdModule();
ad.title = req.body.title;
ad.desc = req.body.desc;
ad.price = req.body.price;
ad.save(err => {
if (err)
res.send('err' + err);
res.json({msg: 'Created'});
})
res.json(req);
});
module.exports = router;
When using post I get req.body is undefined.
My server.js code:
'use strict';
//======================= Base setup =======================\\
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var config = require('./globals/config');
var index = require('./routes/index');
var users = require('./routes/users');
var ads = require('./routes/ads');
var app = express();
//========================= DB =============================\\
mongoose.connect(config.db, () => {
console.log('Connected');
});
//========================= Routes =========================\\
app.use('/', index);
app.use('/users', users);
app.use('/ads', ads);
//========================= Parsers ========================\\
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// app.engine('html', require('ejs').renderFile);
// app.set('view engine', 'html');
//========================= 404 ============================\\
// catch 404 and forward to error handler
// app.use(function(req, res, next) {
// var err = new Error('Not Found');
// err.status = 404;
// next(err);
// });
//
// // error handler
// app.use(function(err, req, res, next) {
// // set locals, only providing error in development
// res.locals.message = err.message;
// res.locals.error = req.app.get('env') === 'development' ? err : {};
//
// // render the error page
// res.status(err.status || 500);
// res.render('error');
// });
//
//==========================================================\\
module.exports = app;
So I am using body parser.
This is how I'm posting with postman:
What can be the reason for this madness?
I'm guessing it's something with server.js but have no idea what.
I was following this tutorial.
https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4#creating-routes-for-a-single-item
Express middlewares executed by order that they are defined, in your case bodyParser defined after ads middleware, just move asd to the bottom
Put your parsers above your routes -- as it happens now, requests are hitting the routes before they have a chance to go through the parsers.