I am using Node.js, Express, and MongoDB for a project and in MongoDB, .save() is not working.
index.js file code:
const express = require("express");
const app = express();
const dotenv = require("dotenv");
const helmet = require("helmet");
const morgan = require("morgan");
const mongoose = require("mongoose");
//middleware;
app.use(express.json()); //for json files;
app.use(helmet());
app.use(morgan("common"));
//routing paths;
const authUser = require("./routes/auth");
// for secrets keys;
dotenv.config();
//Connecting to Mongoose;
mongoose.connect(process.env.MONGO_PATH, {
userNewUrlParser: true, useUnifiedTopology: true
}, () => {
console.log("Connected to MongoDb");
}
)
app.use("/api/auth", authUser);
app.listen(9000, () => {
console.log("Server is Running...");
}
)
Model file name User.js:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserSchema = new Schema({
username: {
type: String,
require: true,
},
password: {
type: String,
require: true,
}
});
const User= mongoose.model("User", UserSchema);
module.exports = User;
auth.js file
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
//for register;
router.get("/register", async (req, res) => {
try {
const newuser = new User({
username: "herovinay",
password: "herovinay"
});
newuser.save((err)=> {
if (err) {
res.status(500).json({ msg: "internal error is here"});
}
else {
res.status(200).json({ msg: "Data saved successfully..." });
}
});
} catch (err) {
res.send("second error is here");
}
})
module.exports = router;
When accessing localhost:9000/api/auth/register, the output is msg: "internal error is here".
Screenshot of output:
Every time I tried to hit that request, the same error came over and over again.
I tried everything and was unable to save my data to the MongoDB cluster.
Change the get method to post. to create new data in the server the post method is used. and also add the await keyword before the newuser.save(),
here is a example.
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
//for register;
router.post("/register", async (req, res) => {
try {
const newuser = new User({
username: "herovinay",
password: "herovinay"
});
await newuser.save((err)=> {
if (err) {
res.status(500).json({ msg: "internal error is here"});
}
else {
res.status(200).json({ msg: "Data saved successfully..." });
}
});
} catch (err) {
res.send("second error is here");
}
})
module.exports = router;
Related
I have a REST API made with Node.js and I use Mongoose to connect with MongoDB. Whenever I try to interact with the DB using Mongoose, I get the timeout error.
I have made sure that the DB is running and accepts connections from my IP. Using the same connection method in other projects works for some reason.
I am using mobile hotspot connection. Could that be an issue?
server.js
const express = require('express');
const app = express();
const cors = require('cors');
const userRoutes = require('../Backend/routes/userRoutes')
const taskRoutes = require('../Backend/routes/taskRoutes')
const mongoose = require('mongoose');
require('dotenv').config()
mongoose.connect(process.env.DB_CONNECTION);
app.use(cors());
app.use(express.json());
app.use(userRoutes)
app.use(taskRoutes)
app.listen(process.env.PORT || 3000 , () => {
console.log("API is now running.")
});
userRoutes.js
const userController = require('../controllers/userController')
const express = require('express');
const router = express.Router();
router.get('/users/currentUser', userController.getCurrentUserData)
router.get('/users/:userId', userController.getUserData)
router.post('/register', userController.register);
router.post('/login', userController.login);
module.exports = router;
Method in userController that causes the error (the error is caused by no matter which method I call out)
exports.login = async (req, res) => {
if (!req.body.username || !req.body.password) {
return res.status(400).send("Missing one or all required request body fields: username, password");
}
let existingUser;
try {
existingUser = await userSchema.findOne({ username: req.body.username });
} catch(err) {
return res.status(500).send("Internal server error."); //Error comes from here
}
if (!existingUser) {
return res.status(404).send('User not found');
}
const isPasswordCorrect = await bcrypt.compare(req.body.password, existingUser.password);
if (!isPasswordCorrect) {
return res.status(401).send('Invalid credentials');
}
let token;
try {
token = jwt.sign(
{ userId: existingUser._id, username: existingUser.username, tasks: existingUser.tasks},
process.env.SECRET,
{ expiresIn: "1h" }
);
} catch (err) {
console.log(err);
return res.status(500).send("Couldn't create JWT.")
}
return res.status(200).json({ token: token });
}
User model
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const userSchema = new mongoose.Schema({
username:{
type: String,
unique: true
},
password:{
type: String
},
tasks:{
type:[mongoose.Types.ObjectId]
}
})
userSchema.pre('save', async function(next) {
const salt = await bcrypt.genSalt();
this.password = await bcrypt.hash(this.password, salt);
next();
});
module.exports = mongoose.model('user',userSchema);
.env
DB_CONNECTION="mongodb://localhost:27017/test"
SECRET='test'
I'm going to develop API using Node Express & Mongo.I have manually entered data to mongo db like below and when i try to get data from the db it shows me empty in postman.Here i have paste my project code for easy to figure out.
In the controller returned empty results.
my project structure looks like this
db.config.json
module.exports = {
//url: "mongodb://localhost:27017/TestDb"
url: "mongodb://localhost:27017/Users"
};
server.js
const express = require("express");
const cors = require("cors");
const app = express();
var corsOptions = {
origin: "http://localhost:8081"
};
app.use(cors(corsOptions));
// parse requests of content-type - application/json
app.use(express.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));
// simple route
app.get("/", (req, res) => {
res.json({ message: "Welcome to Shopping List." });
});
require("./app/routes/user.routes")(app);
// set port, listen for requests
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
const db = require("./app/models");
db.mongoose
.connect(db.url, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("Connected to the database!");
})
.catch(err => {
console.log("Cannot connect to the database!", err);
process.exit();
});
index.js
const dbConfig = require("../config/db.config.js");
const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
const db = {};
db.mongoose = mongoose;
db.url = dbConfig.url;
db.users = require("./user.model.js")(mongoose);
console.log(db.url);
module.exports = db;
user.contoller.js
const db = require("../models");
const User = db.users;
// Retrieve all Tutorials from the database.
exports.findAll = (req, res) => {
User.find({ isAdmin: false })
.then(data => {
console.log("datanew"+data); // <-- Empty returns here.. []
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while retrieving user."
});
});
};
user.model.js
module.exports = mongoose => {
var schema = mongoose.Schema(
{
firstName: String,
lastName: String,
password: String,
email:String,
isAdmin:Boolean
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
const User = mongoose.model("user", schema);
return User;
};
user.route.js
module.exports = app => {
const users = require("../controllers/user.controller.js");
var router = require("express").Router();
// Retrieve all Tutorials
router.get("/", users.findAll);
app.use('/api/users', router);
};
It appears you manually created your MongoDB collection. Users must be in small letters so from the MongoDB interface, change Users => users and you'll be set.
Also your DB connection uri should be:
module.exports = {
url: "mongodb://localhost:27017/TestDb"
};
TestDB is the database while users is the collection. Your uri must point to a db that your code will query collections in.
Your User Model
This is just a slight change but you want to keep your code consistent. User should all be in capitalize form. MongoDB is smart to user plural and small caps automatically in the db.
module.exports = mongoose => {
var schema = mongoose.Schema(
{
firstName: String,
lastName: String,
password: String,
email:String,
isAdmin:Boolean
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
const User = mongoose.model("User", schema);
return User;
};
// Actually you can remove
index.js
db.config.js files
// *********
add in server.js
const express = require('express')
const mongoose = require('monggose')
const app = express()
mongoose.connect('mongodb://localhost/TestDb');
when i run router.post("/signin", async (req, res) from auth.js then cookie is not saving in my local host .
this is index.js
const express = require("express");
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const cors = require("cors");
const { google } = require("googleapis");
const cookieParser= require('cookie-parser');
const app = express();
app.use(cors());
app.use(express.json());
const passport = require("passport");
dotenv.config({ path: "./config.env" });
const db = require("./db/connection");
app.use(require('./router/auth'));
const User= require("./UserSchema/Schma")
const messages=require("./sendMessage/message");
// messages()
// .then((e)=>{console.log(e)})
app.use(cookieParser());
app.listen(3001, (req, res) => {
console.log(`server running at port no 3001`);
});
this is auth.js
const express = require("express");
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt= require('jsonwebtoken');
const User = require("../UserSchema/Schma");
const cookieParser = require("cookie-parser");
const authenticate = require('../middleware/authenticate');
let token;
router.post("/signin", async (req, res) => {
console.log(req.body);
// res.cookie("raushan", "raushan");
try {
const { email, password } = req.body;
if (!email || !password) {
return res.json({ error: "invalid credentials you added " });
}
const details = await User.findOne({ email: email });
console.log(details);
if (!details) {
return res.json({ error: "users error" });
}
else
{
const isMatch = await bcrypt.compare(password,details.password);
console.log(isMatch);
token= await details.generateAuthToken();
console.log(token);
res.cookie("jwtoken",token,{
expiresIn:"1h",
httpOnly:true,
secure:true
}
);
if (!isMatch) {
return res.status(400).json({ error: "invalid credientials" });
} else {
return res.json({ message: "user signin successfully" });
}
}
}
catch {
console.log("something going bad");
res.status(400).json({ error: "sorry something missing" })
}
});
module.exports = router;
and this Schema.js and inside this generateAuthToken() function
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const jwt= require("jsonwebtoken");
const userSchema = new mongoose.Schema({
name: {
type: String,
require:true,
},
email: {
type: String,
require:true,
},
phone :{
type:Number,
require:true,
},
work:{
type:String,
require:true,
},
password:{
type:String,
require:true,
}
,
cpassword:{
type:String,
require:true,
},
tokens:[{
token:{
type:String,
require:true,
}
}]
});
userSchema.pre('save', async function(next) {
if(this.isModified('password'))
{
this.password=await bcrypt.hash(this.password,12);
this.cpassword=await bcrypt.hash(this.cpassword,12);
}
next();
})
userSchema.methods.generateAuthToken= async function(){
try {
let token= jwt.sign({_id:this._id},process.env.SECRET_KEY);
this.tokens=this.tokens.concat({token:token});
await this.save();
return token;
} catch (error) {
console.log(err);
}
}
const User = mongoose.model("USER", userSchema);
module.exports = User;
I am trying it from last two days but i can't get any solution till now please help .
It's not working because of the secure flag in auth.js:
res.cookie("jwtoken",token,{
expiresIn:"1h",
httpOnly:true,
secure:true
}
);
This is a great security practice, but it will not work on localhost because it's not over HTTPS. You need to either:
Disable the secure flag for development only, or
Enable https and use self-signed certificates for localhost development, or
Use a TLS-terminating proxy such as haproxy
I am facing this issue. I looked online for hours to find out what the problem is before posting here. I keep getting this error OverwriteModelError: Cannot overwrite ``user`` model once compiled. after sending a post request via postman and I can't find out what's going on. could you help me find out what's going on? thank you so much in advance!
server.js
const express = require("express");
const app = express();
const user = require("./routes/user");
const connectDB = require("./config/db");
connectDB();
app.use(express.json({extended: false}));
app.get("/", (req, res) => {
res.send("welcome to our api");
});
app.use("/user", user);
const PORT = 3000 || process.env.PORT;
app.listen(PORT, () => {
console.log(`PORT ${PORT} listening and refeshing...`);
});
db.js
const mongoose = require("mongoose");
const connectDB = () =>
mongoose
.connect(
"some database",
{
useNewUrlParser: true,
useUnifiedTopology: true,
}
)
.then(
() => {
console.log("mongoDB conneted");
},
(err) => {
console.log(err);
}
);
module.exports = connectDB;
user.js
const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const {body, validationResult} = require("express-validator");
router.get("/", (req, res) => {
res.send("hello");
});
router.post(
"/",
[
// password must be at least 5 chars long
body("email").isEmail(),
body("password").not().isEmpty(),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty) {
return res.status(400).json({errors: errors.array()});
}
try {
const UsersSchema = mongoose.Schema({
email: {type: String, required: true},
password: {type: String, required: true},
});
var users = mongoose.model("user", UsersSchema);
var user = new users({
email: req.body.email,
password: req.body.password,
});
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(req.body.password, salt);
user.save((err, user1) => {
if (err) {
console.log("error posing user");
throw err;
}
});
console.log(user.id);
const payload = {
user: {
id: user.id,
},
};
} catch (error) {
console.log(error);
res.status(400);
}
}
);
module.exports = router;
Every time the route runs it tries to create a schema which is already created.Mongoose create the collection with the first argument user by converting it to plural i.e. users.
I'm working with nextjs and express .I'm implementing simple signin form.I'm sending user credential and using find() ,checking whether user exist or not.but find() returns empty response.
In terminal find() returns array of that record.
model
const mongoose = require('mongoose')
const schema = mongoose.Schema
const user = new schema({
username: { type: String} ,
password: { type: String},
role: { type: String},
})
module.exports = mongoose.model('user', user);
router.js
const express = require('express')
const router = express.Router()
const user = require('../models/user');
router.post('/user/signin', (req, res) => {
user.find({
username: req.body.username, password: req.body.password
}, (err, user) => {
console.log(user);
if (err) {
result.status(404).send({ error: 'There is some error' });
} else if (user.length == 1) {
var token = 'kkl';//token
res.send({ token });
} else {
console.log(err);
res.send('Incorrect Email and Password');
}
});
})
module.exports = router;
this.is my index.js
const express = require('express')
const next = require('next')
const bodyParser = require('body-parser')
const PORT = process.env.PORT || 4000
const dev = process.env.NODE_DEV !== 'production' //true false
const nextApp = next({ dev })
const handle = nextApp.getRequestHandler() //part of next config
const mongoose = require('mongoose')
const router = express.Router();
nextApp.prepare().then(() => {
const app = express();
const db = mongoose.connect('mongodb://localhost:27017/knowledgeBase')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/knowledgeBase', require('./routes/router'));
app.get('*', (req, res) => {
return handle(req, res) // for all the react stuff
})
app.listen(PORT, err => {
if (err) {
console.log(err);
throw err;
}
console.log(`ready at http://localhost:${PORT}`)
})
})
please help
What response you get when you try this?
According to the response I will edit response.
router.post("/user/signin", async (req, res) => {
if (!req.body.username) return res.status(400).send("username cannot be null");
if (!req.body.password) return res.status(400).send("Password cannot be null");
const user = await User.findOne({ username: req.body.username});
if (!user) return res.status(400).send("User not found");
if (req.body.password!== user.password)
return res.status(400).send("Invalid password.");
res.send("logined");
});