How to solve MongoServerError: E11000 duplicate key error? - javascript

Index.Js File:
const cookieSession = require("cookie-session");
const express = require("express");
const app = express();
const helmet = require("helmet");
const morgan = require("morgan");
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const userRoute = require("./routes/user")
const authRoute = require("./routes/auth")
dotenv.config();
//Mongoose Connect
mongoose.connect(process.env.MONGO_URL, {useNewUrlParser: true}, (err) =>
{
console.log("mongdb is connected");
});
//middleware
app.use(express.json());
app.use(helmet());
app.use(morgan("common"));
app.get("/", (req, res) => {
res.send("Welcome to home page");
})
app.use("/api/auth", authRoute);
app.use("/api/user", userRoute);
app.listen(5000,function(err)
{
if(err)
console.log("Server not connected")
console.log("Connnection is established");
})
Auth.Js File
const router = require("express").Router();
const User = require('../model/Users');
//REGISTER
router.get("/register", async (res,req)=> {
const user = await new User({
username: "gauravnegi",
password: "123456",
email: "gauravnegi#gmail.com",
});
await user.save();
res.send("ok");
});
module.exports = router;
Error:
return callback(new error_1.mongoservererror(res.writeerrors [0] ))
Full Error Snippet:
How to resolve above error?

Dear it is not a server side error it's a client side error b/c you have defined somewhere some field {unique:true} in your model! So you should wrap your function inside try-catch block for example
router.get("/register", async (res,req)=> {
try{
const user = await new User({
username: "gauravnegi",
password: "123456",
email: "gauravnegi#gmail.com",
});
await user.save();
res.send("ok");
}catch(error){
//check if it was a duplication error
if(error.code==11000) // show user that it is unique path
and handle other validation error
}
});

Related

Getting TypeError: User is not a constructor when testing user add with API

I am trying to make my backend work with MongoDB ATLAS.
I'm using express, mongoose and node.js for my tests and when I am trying to test my API routes (in this case to add a user)
The code I have is the following:
users.js
const router = require('express').Router();
const { Router } = require('express');
let User = require('../models/user.model');
router.route('/').get((req, res) => {
User.find()
.then(users => res.json(users))
.catch(err => res.status(400).json('Error: ' + err));
});
router.route('/add').post((req, res) => {
const username = req.body.username;
const newUser = new User({username});
newUser.save()
.then(() => res.json('User added!'))
.catch(err => res.status(400).json('Error: ' + err));
});
module.exports = router
user.model.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
trim: true,
minlength: 3
},
}, {
timestamps: true,
});
const User = mongoose.model('User', userSchema);
module.exports = User;
server.js
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
const port = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, { useNewUrlParser: true, useCreateIndex: true }
);
const connection = mongoose.connection;
connection.once('open', () => {
console.log("MongoDB database connection established successfully");
})
const exercisesRouter = require('./routes/exercises');
const usersRouter = require('./routes/users');
app.use('/exercises', exercisesRouter);
app.use('/users', usersRouter);
app.listen(port, () => {
console.log(`Server is running on port: ${port}`);
});
When I am testing this with postman via a POST I get the following error: I am getting the following error: TypeError: User is not a constructor
The post is done to http over port 5000 with raw json body as "username": "blahblahblah"
Can you help with this maybe?
I am not sure what happened but today I cut and pasted back all the code and the API started to work just fine. Now I can add users without any problems.
Could be a glitch but not sure at this point.

CORS issue with Express Router end points

I have a react app that is making a REST to a an express node server.
The express router defines a bunch of rest endpoints.
When I hit the endpoints in the express router using postman, it works fine.
When I hit the endpoint with me react app, it doesn't. I'm seeing 400 error when my react app makes the call using axios.
This is what my index.js looks like:
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const cors = require("cors");
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
// server.use(bodyParser.json());
app.use(cors());
// app.options("*", cors());
const UserModel = require("./models/User");
mongoose
.connect(
"mongodb"
)
.then(() => console.log("SUCESSFULLY connected to MongoDB!"))
.catch((error) => console.log(`FAILED tot connect to MongoDB: ${error}`));
require("./auth/localStrategyAuth");
const authRoutes = require("./routes/authRoutes");
app.use("/v1", authRoutes);
// app.post("/", (req, res) => {
// res.send("Hello World!");
// });
// app.post("/v1/signup", (req, res) => {
// console.log("lol");
// });
// app.use(express.json());
const PORT = 5000;
app.listen(PORT, () =>
console.log(`ui-rest listening on port localhost:${PORT}`)
);
user.js
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const { Schema } = mongoose;
const UserSchema = new Schema({
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
});
const UserModel = mongoose.model("user", UserSchema);
module.exports = UserModel;
authRoutes.js
const express = require("express");
const passport = require("passport");
const jwt = require("jsonwebtoken");
const JWTstrategy = require("passport-jwt").Strategy;
//We use this to extract the JWT sent by the user
const ExtractJWT = require("passport-jwt").ExtractJwt;
const router = express.Router();
// When the user sends a post request to this route, passport authenticates the user based on the
// middleware created previously
router.post(
"/signup",
passport.authenticate("signup", { session: false }),
async (req, res, next) => {
res.json({
message: "Signup successful",
user: req.user,
});
}
module.exports = router;
localStrategyAuth.js
const passport = require("passport");
const localStrategy = require("passport-local").Strategy;
const UserModel = require("../models/User");
//Create a passport middleware to handle user registration
passport.use(
"signup",
new localStrategy(
{
usernameField: "email",
passwordField: "password",
},
async (email, password, done) => {
try {
// Save the information provided by the user to the the database
const user = await UserModel.create({ email, password });
// Send the user information to the next middleware
return done(null, user);
} catch (error) {
done(error);
}
}
)
);
This is what my express router looks like:
const express = require("express");
const router = express.Router();
router.post(
"/signup",
passport.authenticate("signup", { session: false }),
async (req, res, next) => {
res.json({
message: "Signup successful",
user: req.user,
});
}
);
module.exports = router;
What am I missing? I've set up CORS in the index.js file. I just can't see where I'm going wrong. Why cant my react app hit the express router endpoints.
If I have a normal express endpoint, then my react app is able to hit those endpoints. For example, the endpoint below works fine when my react app hits it.
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
app.post("/", (req, res) => {
res.send("Hello World!");
});
const PORT = 5000;
app.listen(PORT, () =>
console.log(`listening on port localhost:${PORT}`)
app.post("/someSignup", (req, res) => {
console.log("signup");
});
I've also tried things like with no luck:
const authRoutes = require("./routes/authRoutes");
authRoutes.use(cors());
Here is what my react code looks like when it submits the rest call:
// axios setup
axios.create({
baseURL: "http://localhost:5000",
// headers: {
// "Content-Type": "application/json",
// },
});
// Handle submit
handleSubmit = async (event) => {
event.preventDefault();
const newUserData = {
// firstName: this.state.firstName,
// lastName: this.state.lastName,
email: this.state.email,
password: this.state.password,
};
const result = await axios.post("/v1/signup", newUserData);
console.log(result);
};
Here is a screenshot of headers tab on chrome console
Here is a screenshot of response tab on chrome console
Here is a screenshot of the request
400 means bad request, your problem isn't about with cors.
You didn't setup your api to handle JSON data which react sends, so it can't read your request.body and gives 400-Bad Request.
So you need to add this line:
app.use(bodyParser.json());
Also in the current versions of express, body parser isn't required , it comes with express. So you can use it like this:
app.use(express.json());
The reason it worked with postman is that you sent the data in x-www-form-urlencoded.
you can use check my code for cors error.
const express = require('express');
var mongoose = require('mongoose');
const bodyParser = require('body-parser');
var morgan = require('morgan');
var cors = require('cors')
const app = express();
// CORS Middleware
app.use(cors());
// Logger Middleware
app.use(morgan('dev'));
// Bodyparser Middleware
app.use(bodyParser.json());
const MongoClient = require('mongodb').MongoClient;
const uri = "uri";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
client.connect(err => {
console.log('MongoDB Connected...')
const collection = client.db("dbname").collection("collectionname");
app.post('/name', (req, res) => {
collection. insertOne({ name: req.body.name })
res.send("data added")
});
});
const port = process.env.PORT || 5000;
app.listen(port, function () {
console.log(`Example app listening on port ${port}`);
});
You need to register the cors middleware into express app.
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
app.use(cors());
app.post("/", (req, res) => {
res.send("Hello World!");
});
const PORT = 5000;
app.listen(PORT, () => console.log(`listening on port localhost:${PORT}`)

Why does save function in express not work?

This is my first day in express. I was trying to create a simple route but my save function doesn't seem to work. I tried looking at similar questions posted on stackoverflow but couldn't make it. Any help will be appreciated.
const express = require("express");
const router = express.Router();
const Post = require("../models/Post");
//ROUTES
router.post('/', (req, res) => {
const post = new Post({
title: req.body.title,
description: req.body.description
})
post.save()
.then(data => {
res.json(data);
})
.catch(err => {
res.json(err);
});
});
module.exports = router;
And here is my model.
const mongoose = require("mongoose");
const PostSchema = mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
}
});
module.exports = mongoose.model('Posts',PostSchema);
app.js code
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
require("dotenv/config");
//IMPORT ROUTES
const postsRoute = require("./routes/posts");
//MIDDLEWARE - Function that always execute when routes are being hit.
app.use(bodyParser.json())
app.use('/posts', postsRoute)
//app.use('/users', usersRoute)
//ROUTES
app.get('/', (req, res) => {
res.send("We are on home");
});
//CONNECT TO DB
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true },
() => {
console.log("DB Connected!!")
})
//How do we start listening to the server
app.listen(3000);
My postman query -
Postman Response -
Please let me know if you need any more information.
your app.js should be :
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
require("dotenv/config");
//MIDDLEWARE - Function that always execute when routes are being hit.
app.use(bodyParser.json())
mongoose.connect(process.env.DB_CONNECTION, { useNewUrlParser: true }, function(err) {
if (err) {
console.error('System could not connect to mongo server')
console.log(err)
process.exit()
} else {
console.log('System connected to mongo server')
}
});
//ROUTES
app.get('/', (req, res) => {
res.send("We are on home");
});
//IMPORT ROUTES
const postsRoute = require("./routes/posts");
app.use('/posts', postsRoute)
app.listen(3000);
also add console log in router to check req.body :
router.post('/', (req, res) => {
console.log('req.body===',req.body);
...
});

Save data to MongoDB using NodeJS

I am trying to pass data to a MongoDB collection and it returns Cannot POST /courseweb/course/add
Before passing values through axios I tried postman (a google extension) to send data.
This is my server.js which is implemented with expressjs
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const Bundler = require("parcel-bundler");
const cors = require("cors");
const mongoose = require("mongoose");
const InstructorDB = require('./public/DBModels/InstructorDB');
const router = express.Router();
const bundler = new Bundler("./src/index.html");
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(bundler.middleware());
// app.use(express.static('./src'));
app.use("/courseweb", router);
mongoose.connect("mongodb://127.0.0.1:27017/courseweb", {
useNewUrlParser: true
});
const connection = mongoose.connection;
connection.once("open", () => {
console.log("Connected to MongoDB via 27017");
});
app.listen(3000, err => {
if (err) {
console.error(err);
process.exit(-1);
}
console.log("Application is running on port 3000");
});
app.get("/", function(req, res) {
res.sendFile("./dist/index.html");
});
router.route('/course/add').post((req, res) => {
let instructorDB = new InstructorDB(req.body);
instructorDB.save().then(bookDB => {
res.status(200).send(`${bookDB} Added`);
}).catch((err) => {
res.status(400).send({message: err});
});
});
router.route('/courses').get((req, res) => {
// name of the course database model here
InstructorDB.find().count(function(err, count){
res.status(200).send(count);
});
});
And this is my InstructorDB.js which is a schema model by mongoose
const mongoose= require('mongoose');
const Schema = mongoose.Schema;
let InstructorDB = new Schema({
firstName: String,
lastName: String,
designation: String,
faculty: String,
contactNumber: Number,
email: String,
password: String,
isEnabaled: Boolean,
courses: [{courseID: String}]
});
module.exports = mongoose.model('InstructorDB', InstructorDB, 'InstructorDB');
And this is a screenshot and the response I get when I pass the values through postman. I have set header as content-type and application/json too
Can anyone tell me where I have gone wrong?
Make sure you send the right data via your post request and change the verb to post :
app.post('/course/add', (req, res) => {
if(req.body == null){
return res.status(400).send({message: 'bad request'});
}
let instructorDB = new InstructorDB(req.body);
instructorDB.save((err ,doc ) => {
if(err){
res.status(400).send({message: err});
}
res.status(200).send(`Added`);
});
});
You don't need router if you're going to put it in the same file.
try this syntax instead:
app.post('/coureweb/course/add',((req, res) => {
let instructorDB = new InstructorDB(req.body);
instructorDB.save().then(bookDB => {
res.status(200).send(`${bookDB} Added`);
}).catch((err) => {
res.status(400).send({message: err});
});
}));
then take out
app.use("/courseweb")

Error: Illegal arguments: undefined, string

I've been struggling with Bcrypt on my MERN project, I'm trying to run tests on Postman (registration process), but every time I try it I get this error: Error: Illegal arguments: undefined, string on this line:
if (err) throw err;
This is my server main config file:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const users = require('./routes/api/users');
const profile = require('./routes/api/profile');
const posts = require('./routes/api/posts');
const app = express();
// Body parser Middleware
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
// MongoDB Config
const db = require('./config/keys').mongoURI;
// MongoDB Connection
mongoose
.connect(db)
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
app.get('/', (req, res) => res.send('Hello!'));
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server Runing on port ${port}`));
// Using Routes
app.use('/api/users', users);
app.use('/api/profile', profile);
app.use('/api/posts', posts);
And this is the users config file where I'm getting the error:
const express = require('express');
const router = express.Router();
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');
// Load user model:
const User = require('../../models/User');
router.get('/test', (req, res) => res.json({ msg: "Users Works" }));
router.post('/register', (req, res) => {
User.findOne({ email: req.body.email })
.then(user => {
if (user) {
return res.status(400).json({ email: "Email already exists" });
} else {
const avatar = gravatar.url((req.body.email, {
s: '200', // Size
r: 'pg', // Rating
d: 'mm' // Default image
}));
const newUser = new User({
name: req.body.name,
email: req.body.email,
avatar,
password: req.body.password
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser.save()
.then(user => res.json(user))
.catch(err => console.log(err));
})
})
}
})
})
module.exports = router;
this is what I see on Postman:
I've been reviewing it and it doesn't seem to have any error, and I really don't get why is telling me "undefined string". If you see any error that I'm not noticing I will truly appreciate your feedback, Thanks in advance!
const newUser = new User({
name: req.body.name,
email: req.body.email,
avatar, <------------------------- avatar:'', or avatar:null,
password: req.body.password
});

Categories