I am very new to programming and am following a tutorial to learn.
I am stuck and am unable to post new entries using the code and am unable to find what am I missing here.
Any help will be appreciated.
When I am trying to post using postman, I am getting a Validation error, and when I am trying to get values I am getting [].
Edit: Error Msg: "msg":" Error: ValidationError: first_name: Path first_name is required., last_name: Path last_name is required., email: Path email is required."}
// importing modules
var express = require('express');
var mongoose = require('mongoose');
var bodyparser = require('body-parser');
var cors = require('cors');
var path = require('path');
var app = express();
const route = require('./routes/route');
//connect to mongoDB
mongoose.connect('mongodb://localhost:27017/contactlist');
//on connection
mongoose.connection.on('connected', () => {
console.log('Connected to database mongoDB # 27017');
});
//on error
mongoose.connection.on('error', (err) => {
if (err) {
console.log('Error in DB connection' + err);
}
});
//port no
const port = 3000;
//adding middleware
app.use(cors());
//body - parser
app.use(bodyparser.json());
//static files
app.use(express.static(path.join(__dirname, 'public')));
//routes
app.use('/api', route);
//testing server
app.get('/', (req, res) => {
res.send('cutard');
});
app.listen(port, () => {
console.log('Server started at port:' + port);
});
const express = require('express');
const router = express.Router();
const Contact = require('../models/contacts');
//retriving contact
router.get('/contacts', (req, res, next) => {
Contact.find(function (err, contacts) {
res.json(contacts);
})
});
//add contact
router.post('/contacts', (req, res, next) => {
console.log(req.body)
let newContact = new Contact({
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email
});
newContact.save((err, Contact)=>{
if (err) {
res.json({ msg: ' Error: '+err});
}
else {
res.json({ msg: 'Contact added successfully' });;
}
});
});
//delete contact
router.delete('/contact/:id', (req, res, next) => {
Contact.remove({ _id: req.params.id }, function (err, result){
if (err) {
res.json(err);
}
else {
res.json(result);
}
});
});
module.exports = router;
const mongoose = require('mongoose');
const ContactSchema = mongoose.Schema({
first_name: {
type: String,
required: true
},
last_name: {
type: String,
required: true
},
email: {
type: String,
required: true
}
});
const Contact = module.exports = mongoose.model('Contact', ContactSchema);
In your req.body there are obviously no values.
Can you confirm that your body you send in postman looks like this?
{
"first_name": "xxx",
"last_name": "yyy",
"email": "zzz"
}
Also its very important to have Content-Type header set to application/json. Postman will add it automatically, if you choose JSON as format:
The problem is with the installation of body parser.
npm link body-parser
Related
EDIT: #LawrenceCherone solved this, its (req, res, next) not (err, res, req)
I am creating a MERN app (Mongo, express, react, node).
I have some routes that work fine and return data from mongodb. However I created a new controller to access a separate collection and whenever i try to create a new document in it my req.body returns undefined.
I have setup my server.js like this:
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const connectDB = require("./db");
const app = express();
const apiPort = 3000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());
app.use(bodyParser.json());
connectDB();
app.use("/api", require("./routes/router"));
var server = app.listen(apiPort, () => console.log(`Server running on port ${apiPort}`));
module.exports = server;
My router looks like this:
const express = require("express");
const QuizController = require("../controllers/quiz-controller");
const UserController = require("../controllers/user-controller");
const router = express.Router();
// quiz routes
router.post("/quizzes", QuizController.createQuestion);
router.get("/quizzes", QuizController.getAllQuestions);
router.get("/quizzes/:quiz_name", QuizController.getQuestionsByQuiz);
router.get("/quizzes/questions/:question_id", QuizController.getQuestionById);
router.put("/quizzes/:question_id/edit", QuizController.updateQuestionById);
router.delete("/quizzes/:question_id", QuizController.deleteQuestionById);
// user routes
router.post("/users", UserController.createUser);
module.exports = router;
All of the /quizzes routes work perfectly fine and i have had no trouble accessing the body. The UserController.createUser method is almost identical to Quizcontroller.createQuestion too so I am very confused.
Here is the user-controller with the createUser function:
const User = require("../models/User");
createUser = async (err, res, req) => {
const body = req.body;
console.log(req.body);
console.log(req.params);
console.log(body);
if (!body) {
return res.status(400).json({
succes: false,
error: "You must provide a body",
});
}
try {
const newUser = new User(body);
console.log(newUser);
if (!newUser) {
return res.status(400).json({ success: false, error: err });
}
const user = await newUser.save();
return res
.status(200)
.json({ success: true, newUser: user, msg: "New user created" });
} catch (err) {
console.error(err.message);
res.status(500).send("Server error");
}
};
module.exports = { createUser };
Here is an image of the postman request I am using to try test this:
[1]: https://i.stack.imgur.com/UHAK5.png
And the user model:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: true,
},
emailAddress: {
type: String,
required: true,
},
permission: {
type: String,
required: true,
},
auth0Id: {
type: String,
required: true,
},
});
module.exports = mongoose.model("users", UserSchema);
The functional parameter order matters.
its
createUser = async (req, res, next) => // correct format
Not
createUser = async (err, res, req) // wrong format
When I am trying to send POST request, it returns 404, although all routes is right.
I've rummaged through tons of similar questions but I didn't find anything that seems to solve my problem.
Here's a code:
App.js
const http = require('http');
const url = require('url');
const express = require('express');
const mongoose = require('mongoose');
const path = require('path');
const bodyParser = require('body-parser');
const passport = require('passport');
mongoose.connect('mongodb://localhost:27017/mydb');
let db = mongoose.connection;
db.once('open', () => {
console.log('Connected to Database');
});
db.on('error', (err) => {
console.log(err);
});
const server = express();
server.use(express.static('dist', { extensions: ['html'] }));
let users = require('./routes/users');
server.use(users);
server.use(function (req, res, next) {
res.status(404).sendFile(path.join(__dirname+'/dist/404.html'));
});
const port = process.env.port || 3000;
server.listen(port, () => {
console.log(`Server has been established on port ${port}`)
});
./models/user.js
const User = mongoose.Schema({
name: {
type: String,
required: true
},
lastname: {
type: String,
required: true
},
login: {
type: String,
required: true
},
password: {
type: String,
required: true
},
b_day: {
type: String,
required: true
},
b_month: {
type: String,
required: true
},
b_year: {
type: String,
required: true
},
gender: {
type: String,
required: true
}
});
const user = module.exports = mongoose.model('User', User);
./routes/users.js
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
let User = require('../models/user');
//Register Form
router.get('/signup', (req, res) => {
console.log(res);
res.render('signup');
});
//Register Process
router.post('signup', (req, res) => {
const name = req.body.name;
const lastname = req.body.lastname;
const login = req.body.login;
const password = req.body.password;
const password2 = req.body.repeat_password;
const b_day = req.body.b_day;
const b_month = req.body.b_month;
const b_year = req.body.b_year;
const gender = req.body.gender;
req.checkBody('name', 'Name is required').notEmpty();
req.checkBody('lastname', 'Lastname is required').notEmpty();
req.checkBody('login', 'Login is required').notEmpty();
req.checkBody('password', 'Password is required').notEmpty();
req.checkBody('password2', 'Passwords do not match').equals(req.body.password);
req.checkBody('b_day', 'Birth day is required').notEmpty();
req.checkBody('b_month', 'Birth month is required').notEmpty();
req.checkBody('b_year', 'Birth year is required').notEmpty();
req.checkBody('gender', 'Gender is required').notEmpty();
let errors = req.validationErrors();
if(errors) {
res.render('signup', {
errors:errors
});
} else {
let newUser = new User({
name:name,
lastname:lastname,
login:login,
password:password,
gender:gender,
b_day:b_day,
b_month:b_month,
b_year:b_year
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if(err) {
console.log(err);
}
newUser.password = hash;
newUser.save((err) => {
if(err) {
console.log(err);
return;
} else {
req.flash('success', 'You are now registered');
res.redirect('signin');
}
});
});
});
}
});
router.get('signin', (req, res) => {
res.render('signin');
});
router.post('signin', (req, res, next) => {
passport.authenticate('local', {
successRedirect:'profile',
failureRedirect:'signin',
failureFlash: true
})(req, res, next);
});
router.get('logout', (req, res) => {
res.render('logout');
req.flash('success', 'You are logged out');
res.redirect('signin');
});
module.exports = router;
And also project structure
├── dist
├── routes
│ └── users.js
├── models
│ └── user.js
└── app.js
I expect it will process all data from sign up form and then redirect to sign in page.
Your routes are correct. Error 404 only comes if a route is not found. In your case, its happening because you have not added "/" before calling signup(post request) and signin routes as well in users.js.
Right now your api url is becoming like this :
localhost:3000/userssignin
which should be :
localhost:3000/users/signin
So, your routes should be :
router.post('/signup', (req, res) => {
router.get('/signin', (req, res) => {
router.post('/signin', (req, res) => {
i don't know, but from a first view, i think that you are missing dash before routes
router.get('signin', (req, res) => { // '/singin'
res.render('signin');
});
router.post('signin', (req, res, next) => { // '/singin'
passport.authenticate('local', {
successRedirect:'profile',
failureRedirect:'signin',
failureFlash: true
})(req, res, next);
});
router.get('logout', (req, res) => { // '/logout'
res.render('logout');
req.flash('success', 'You are logged out');
res.redirect('signin');
});
I am working on a rest api based on this tutorial from Joshmorony, I keep running on error "Could not get any response" while testing on Postman. I have tied consuming the end points on ionic3 project but still running on the same problem. What am I doing wrong that might be leading to this error? I would appreciate your support.
Here is my code.
In the controller folder controllers/authentication.js
const jwt = require('jsonwebtoken');
const bluebird = require('bluebird');
const nodemailer = require('nodemailer');
const User = require('../models/user');
const authConfig = require('../config/auth');
const crypto = bluebird.promisifyAll(require('crypto'));
/**
* Generating JWT tokens
*
*/
function generateToken(user){
return jwt.sign(user, authConfig.secret, {
expiresIn: 10080
});
}
function setUserInfo(request){
return {
_id: request._id,
email: request.email,
role: request.role
};
}
/**
* Local login authentication
*
*/
exports.login = function(req, res, next){
var userInfo = setUserInfo(req.user);
res.status(200).json({
token: 'JWT ' + generateToken(userInfo),
user: userInfo
});
}
/**
* Local registration
*
*/
exports.register = function(req, res, next){
var email = req.body.email;
var password = req.body.password;
var role = req.body.role;
if(!email){
return res.status(422).send({error: 'You must enter an email address'});
}
if(!password){
return res.status(422).send({error: 'You must enter a password'});
}
User.findOne({email: email}, function(err, existingUser){
if(err){
return next(err);
}
if(existingUser){
return res.status(422).send({error: 'That email address is already in use'});
}
var user = new User({
email: email,
password: password,
role: role
});
user.save(function(err, user){
if(err){
return next(err);
}
var userInfo = setUserInfo(user);
res.status(201).json({
token: 'JWT ' + generateToken(userInfo),
user: userInfo
})
});
});
}
/**
* Roles Creation
*
*/
exports.roleAuthorization = function(roles){
return function(req, res, next){
var user = req.user;
User.findById(user._id, function(err, foundUser){
if(err){
res.status(422).json({error: 'No user found.'});
return next(err);
}
if(roles.indexOf(foundUser.role) > -1){
return next();
}
res.status(401).json({error: 'You are not authorized to view this content'});
return next('Unauthorized');
});
}
}
In the model folder model/User.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
var UserSchema = new mongoose.Schema({
email: {
type: String,
lowercase: true,
unique: true,
required: true
},
password: {
type: String,
required: true
},
role: {
type: String,
enum: ['reader', 'creator', 'editor'],
default: 'reader'
},
passwordResetToken: String,
passwordResetExpires: Date,
profile: {
name: String,
gender: String,
location: String,
picture: String
}
}, {
timestamps: true
});
UserSchema.pre('save', function(next){
var user = this;
var SALT_FACTOR = 5;
if(!user.isModified('password')){
return next();
}
bcrypt.genSalt(SALT_FACTOR, function(err, salt){
if(err){
return next(err);
}
bcrypt.hash(user.password, salt, null, function(err, hash){
if(err){
return next(err);
}
user.password = hash;
next();
});
});
});
UserSchema.methods.comparePassword = function(passwordAttempt, cb){
bcrypt.compare(passwordAttempt, this.password, function(err, isMatch){
if(err){
return cb(err);
} else {
cb(null, isMatch);
}
});
}
module.exports = mongoose.model('User', UserSchema);
Routes routes.js
const AuthenticationController = require('./controllers/authentication'),
TodoController = require('./controllers/todo'),
express = require('express'),
passportService = require('./config/passport'),
passport = require('passport');
const requireAuth = passport.authenticate('jwt', {session: false}),
requireLogin = passport.authenticate('local', {session: false});
module.exports = function(app){
var apiRoutes = express.Router(),
authRoutes = express.Router(),
todoRoutes = express.Router();
// Auth Routes
apiRoutes.use('/auth', authRoutes);
authRoutes.post('/register', AuthenticationController.register);
authRoutes.post('/login', requireLogin, AuthenticationController.login);
authRoutes.post('/forgot', AuthenticationController.postForgot);
authRoutes.post('/reset/:token', AuthenticationController.postReset);
authRoutes.post('/account/profile', requireAuth, AuthenticationController.postUpdateProfile);
authRoutes.post('/account/password', requireAuth, AuthenticationController.postUpdatePassword);
authRoutes.get('/protected', requireAuth, function(req, res){
res.send({ content: 'Success'});
});
// Set up routes
app.use('/api', apiRoutes);
}
and lastly app.js file
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const errorHandler = require('errorhandler');
const chalk = require('chalk');
const logger = require('morgan');
const bodyParser = require('body-parser');
const cors = require('cors');
const dotenv = require('dotenv');
const databaseConfig = require('./app/config/database');
const router = require('./app/routes');
/**
* Load environment variables from .env file, where API keys and passwords are configured.
*/
dotenv.load({ path: '.env' });
/**
* Connect to MongoDB.
*/
mongoose.Promise = global.Promise;
mongoose.createConnection(process.env.MONGODB_URI || process.env.MONGOLAB_URI);
mongoose.connection.on('error', (err) => {
console.error(err);
console.log('%s MongoDB connection error. Please make sure MongoDB is running.', chalk.red('✗'));
process.exit();
});
/**
* Express configuration.
*/
app.set('host', process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0');
app.set('port', process.env.PORT || process.env.OPENSHIFT_NODEJS_PORT || 8080);
/**
* Error Handler.
*/
app.use(errorHandler());
/**
* Start Express server.
*/
app.listen(app.get('port'), () => {
console.log('%s App is running at http://localhost:%d in %s mode', chalk.green('✓'), app.get('port'), app.get('env'));
console.log(' Press CTRL-C to stop\n');
});
app.use(bodyParser.urlencoded({ extended: false })); // Parses urlencoded bodies
app.use(bodyParser.json()); // Send JSON responses
app.use(logger('dev')); // Log requests to API using morgan
app.use(cors());
router(app);
I managed to get the error, when I was ruling the app in the terminal I got this error "DeprecationWarning: open() is deprecated in mongoose >= 4.11.0, use openUri() instead, or set the useMongoClient option if using connect() or createConnection(). See http://mongoosejs.com/docs/connections.html#use-mongo-client", when I try to modify mongoose.connect(process.env.MONGODB_URI || process.env.MONGOLAB_URI); to mongoose.createConnection(process.env.MONGODB_URI || process.env.MONGOLAB_URI); thats when I get that error of "Could not get any response". Just opted to go with the old connect(). Hope this will help someone experiencing the same issue.
I am trying to save a user to mongodb database using post request as follow, but I got the error TypeError: User is not a constructor. It's a pretty simple set up of the code but i can't figure out anything wrong with it.
//models/users.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const confic = require('../models/users');
// User schema
const UserSchema = mongoose.Schema({
name: {
type: String,
},
email: {
type: String,
required: true
},
username:{
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const User = module.exports = mongoose.model('User', UserSchema);
module.exports.getUserById = function(id,callback){
User.findById(id,callback);
}
module.exports.getUserByUsername = function(username,callback){
const query = {username:username}
User.findOne(query,callback);
}
module.exports.addUser= function (newUser, callback) {
bcrypt.gensalt(10,(err,salt) => {
bcrypt.hash(newUser.password, salt , (err, hash) =>{
if(err) throw err;
newUser.password=hash;
newUser.save(callback);
});
});
}
routes/users.js
//routes/users.js
const express = require('express');
const router = express.Router();
const passport = require('passport');
const jwt = require('jsonwebtoken');
User = require('../models/users');
// // Register
router.post('/register', (req, res, next) => {
var newUser = new User({
name: req.body.name,
email: req.body.email,
username: req.body.username,
password: req.body.password
});
User.addUser(newUser, (err, User) => {
if(err){
res.json({success: false, msg:'Failed to register user'});
} else {
res.json({success: true, msg:'User registered'});
}
});
});
// Authenticate
router.post('/authenticate', (req, res, next) => {
res.send('AUTHENTICATE');
});
// Profile
router.get('/profile', (req, res, next) => {
res.send('PROFILE');
});
module.exports = router;
I am using Postman chrome to send data but it is not showing user registered according to program.
You are exporting your user model from a different file and trying to import from a different file.
change this line:
const User = require('../config/database');
to this:
const User = require('../models/users') # import your user model
I am learning mongodb, but I am running to this wall, and I don't know how to fix it. Please help! It worked before but this time when I make post request I get this error message in Postman "User validation"
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt-nodejs');
var UserSchema = new Schema({
name: String,
username: { type: String, required: true, index: { unique: true }},
password: { type: String, required: true, select: false }
});
UserSchema.pre('save', function(next) {
var user = this;
if (!user.isModified('password')) return next();
bcrypt.hash(user.password, null, null, function(err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
UserSchema.methods.comparePassword = function(password) {
var user = this;
return bcrypt.compareSync(password, user.password);
};
module.exports = mongoose.model('User', UserSchema);
var express = require('express');
var app = express();
var bodyParser = require("body-parser");
var morgan = require('morgan');
var mongoose = require('mongoose');
var port = process.env.PORT || 8080;
var User = require('./app/models/user');
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(function(req,res,next){
res.setHeader('Acess-control-allow-Origin', '*');
res.setHeader('Acess-control-Allow-Methods', 'GET, POST');
res.setHeader('Acess-Control-Allow-Headers', 'X-Requested-With, content-type,\Authorization');
next();
});
app.use(morgan('dev'));
mongoose.connect('mongodb://localhost:27017/myDatabase');
app.get('/', function(req, res){
res.send('Welcome to thome page');
});
var apiRouter = express.Router();
apiRouter.use(function(req, res, next){
console.log('Somebody just came to our app');
next();
});
apiRouter.get('/', function(req, res){
res.json({message: 'Hooray! Welcome to our api1'});
});
app.use('/api', apiRouter);
apiRouter.route('/users')
.post(function(req,res){
var user = new User();
user.name = req.body.name;
user.username = req.body.username;
user.password = req.body.password;
user.save(function(err){
if(err){
if(err.code == 1000)
return res.json({success: false, message: "A user with that username already exists"});
else
return res.send(err);
}
res.json({message: "User created"});
});
});
app.listen(port);
console.log("Magic happens on port " + port);
I had this problem with postman too.
then i decided to use raw data instead of x-www-form-urlencoded with Json(application/json) header.
In your case you can use it like this :
{"name" : "Holly",
"username" : "Hollylawly",
"password" : "supersecret"}
the image for postman req
I fixed by reinstalling postman.
Thank you guys for taking your time to answer the question.
Thanks.