When i wanna save a user with this code:
const router = require("express").Router();
const User = require("../model/User");
//validate
const joi = require("#hapi/joi");
const schema = joi.object({
name: joi.string().min(1).max(255).required(),
email: joi.string().max(255).email().required(),
password: joi.string().min(8).max(255).required(),
});
router.post("/register", async (request, respond) => {
const { error } = schema.validate(request.body);
if (error) return respond.status(400).send(error.details[0].message);
const user = new User({
name: request.body.name,
email: request.body.email,
password: request.body.password,
});
try {
const savedUser = await user.save();
respond.send(savedUser);
} catch (err) {
respond.status(500).send(err);
}
});
module.exports = router;
it doesnt get any error but it also does not respond anything and does not save anything
I don't see any client connection in your code. Don't forget to connect to your mongoDB server and open your connection before processing any operation. Otherwise it won't have any effect.
var db = new Db('test', new Server('localhost', 27017));
// Establish connection to db
db.open((err, db) => {
// Do what you want
});
See this example of saving a document in nodeJS: Save to MongoDB
Related
file user.js
const mongoose = require("mongoose");
const User = new mongoose.Schema({
name: String,
age: Number,
});
module.exports = mongoose.model("user", User);
app.js which I run database and connect
app.post("/createUser", async (req, res) => {
try {
//console.log(req.body);
const myUser = new User(req.body);
const saveUser = await myUser.save();
res.send(myUser);
} catch (err) {
res.status(500).json(err);
}
});
I try to add data in postman:{"name":"Ngan", "age":21}, but it displays fail
i have two test files that connect with mongoose, the problem started when i added the second one
i tried to use jest.useFakeTimers() after imports but nothing changed
here is the test file
const mongoose = require("mongoose");
const supertest = require("supertest");
const app = require("../app");
const api = supertest(app);
const User = require("../models/user");
const bcrypt = require("bcryptjs");
describe("adding users", () => {
beforeEach(async () => {
await User.deleteMany({});
const passwordHash = await bcrypt.hash("sekret", 10);
const user = new User({ username: "root", passwordHash });
await user.save();
});
test("adding users successfuly", async () => {
const newUser = {
name: "john oliver",
username: "karana",
password: "ooiiu",
};
await api.post("/api/users").send(newUser).expect(200);
});
});
afterAll(() => {
mongoose.connection.close();
});
and here is the mongoose model
const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");
const userSchema = new mongoose.Schema({
name: String,
username: {
type: String,
unique: true,
minlength: 3,
},
passwordHash: String,
});
userSchema.plugin(uniqueValidator);
userSchema.set("toJSON", {
transform: (document, returnedObject) => {
returnedObject.id = returnedObject._id.toString();
delete returnedObject._id;
delete returnedObject.__v;
delete returnedObject.passwordHash;
},
});
module.exports = mongoose.model("User", userSchema);
here is the controller
const bcrypt = require("bcryptjs");
const usersRouter = require("express").Router();
const User = require("../models/user");
usersRouter.get("/", async (req, res) => {
const users = await User.find({});
res.json(users);
});
usersRouter.post("/", async (req, res, next) => {
const body = req.body;
if (body.password.length >= 3) {
const saltRounds = 10;
const passwordHash = await bcrypt.hash(body.password, saltRounds);
const user = new User({
name: body.name,
username: body.username,
passwordHash,
});
try {
const result = await user.save();
res.status(200).json(result);
} catch (err) {
next(err);
}
} else {
res
.status(400)
.json({ error: "password must be atleast 3 charecters long" });
}
});
module.exports = usersRouter;
*and there router is * app.use("/api/users", usersRouter); as written in the app.js files.
here is the error am getting
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.
at BufferList.Readable (node_modules/readable-stream/lib/_stream_readable.js:179:22)
at BufferList.Duplex (node_modules/readable-stream/lib/_stream_duplex.js:67:12)
at new BufferList (node_modules/bl/bl.js:33:16)
at new MessageStream (node_modules/mongodb/lib/cmap/message_stream.js:35:21)
at new Connection (node_modules/mongodb/lib/cmap/connection.js:54:28)
C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\readable-stream\lib\_stream_readable.js:111
var isDuplex = stream instanceof Duplex;
^
TypeError: Right-hand side of 'instanceof' is not callable
at new ReadableState (C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\readable-stream\lib\_stream_readable.js:111:25)
at BufferList.Readable (C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\readable-stream\lib\_stream_readable.js:183:25)
at BufferList.Duplex (C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\readable-stream\lib\_stream_duplex.js:67:12)
at new BufferList (C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\bl\bl.js:33:16)
at new MessageStream (C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\mongodb\lib\cmap\message_stream.js:35:21)
at new Connection (C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\mongodb\lib\cmap\connection.js:54:28)
at C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\mongodb\lib\core\connection\connect.js:36:29
at callback (C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\mongodb\lib\core\connection\connect.js:280:5)
at TLSSocket.connectHandler (C:\Users\oussama\Desktop\web-projects\fullstackopen-part4\node_modules\mongodb\lib\core\connection\connect.js:325:5)
at Object.onceWrapper (events.js:421:28)
at TLSSocket.emit (events.js:315:20)
at TLSSocket.onConnectSecure (_tls_wrap.js:1530:10)
at TLSSocket.emit (events.js:315:20)
at TLSSocket._finishInit (_tls_wrap.js:936:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:710:12)
the error happen after saving the data (users) to mongoDB.
thanks in advance.
I resolved this by using the jest-mongodb preset which supplies all the async config necessary for Jest to run smoothly with MongoDB.
Note that Mongoose doc warns against using jest.useFakeTimers() because they "stub out global functions like setTimeout() and setInterval(), which causes problems when an underlying library uses these functions"
I'm really new to NodeJs and MongoDB or web development in general. I'm following a tutorial on how to make a registration system that was posted about 2 years ago. With these codes below, he was able to send a post request test using postman and his data was saved into MongoDB, however, when I try to send a post request on postman, it keeps loading at "sending request" and data was never saved to mongoDB...I'm not sure if nodejs has changed syntax or if i'm doing something wrong... please help!!
this is the code for user.controller.js
const mongoose = require('mongoose');
const User = mongoose.model('User');
module.exports.register = (req, res, next) => {
var user = new User();
user.fullName = req.body.fullName;
user.email = req.body.email;
user.password = req.body.password;
user.save((err, doc) => {
if (!err)
res.send(doc);
else {
if (err.code == 11000)
res.status(422).send(['Duplicate email adrress found.']);
else
return next(err);
}
});
this is the code for user.model.js:
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
var userSchema = new mongoose.Schema({
fullName: {
type: String
},
email: {
type: String
},
password: {
type: String
},
saltSecret: String
});
// Events
userSchema.pre('save', function (next) {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(this.password, salt, (err, hash) => {
this.password = hash;
this.saltSecret = salt;
next();
});
});
});
mongoose.model('User', userSchema);
this is the code for server(app.js)
const MongoClient = require('mongodb').MongoClient;
const uri = process.env.MONGODB_URI;
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
client.connect(err => {
const collection = client.db("test").collection("devices");
// perform actions on the collection object
console.log(`MONGODB CONNECTION SUCCEEDED`);
client.close();
});
require('./user.model');
In controller you have mongoose to write data to mongo but in your server file you are connecting to mongodb using native mongo driver. Hence, it won't work. Either both places you need to have mongodb native driver or mongoose.
Use below code where I have modified the server start file to use mongoose.
const mongoose = require('mongoose'),
const m_url = 'mongodb://127.0.0.1:27017/',
db_name = 'test', // use your db name
m_options = {
'auto_reconnect': true,
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true
}
mongoose.connect(m_url + db_name, m_options, function (err) {
if (err) {
console.log('Mongo Error ' + err);
} else {
status.mongo = 'Running'
console.log('MongoDB Connection Established');
}
});
// import/require user controller.
so hello everyone i'm devolpping my authentication backend i set up my routers my models middlewares and everything then i tried to use postman to see if the registation work or not and each time i click on send request nothing happen i don't know what should i do exactly so please can anyone help with this
database/db.js // connection to database
const mongoose = require('mongoose')
require('dotenv').config();
const base = process.env.MONGO_DATA;
try {
mongoose.connect( base,
{useNewUrlParser: true, useCreateIndex: true}, () =>
console.log("database connected"));
}catch (error) {
console.log("could not connect");
}
models/user.model.js
const mongoose = require('mongoose')
const validator = require('validator')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const userSchema = mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
unique: true,
lowercase: true,
validate: value => {
if (!validator.isEmail(value)) {
throw new Error({error: 'Invalid Email address'})
}
}
},
password: {
type: String,
required: true,
minLength: 7
},
tokens: [{
token: {
type: String,
required: true
}
}]
})
userSchema.pre('save', async function (next) {
// Hash the password before saving the user model
const user = this
if (user.isModified('password')) {
user.password = await bcrypt.hash(user.password, 8)
}
next()
})
userSchema.methods.generateAuthToken = async function() {
// Generate an auth token for the user
const user = this
const token = jwt.sign({_id: user._id}, process.env.JWT_KEY)
user.tokens = user.tokens.concat({token})
await user.save()
return token
}
userSchema.statics.findByCredentials = async (email, password) => {
// Search for a user by email and password.
const user = await User.findOne({ email} )
if (!user) {
throw new Error({ error: 'Invalid login credentials' })
}
const isPasswordMatch = await bcrypt.compare(password, user.password)
if (!isPasswordMatch) {
throw new Error({ error: 'Invalid login credentials' })
}
return user
}
const User = mongoose.model('User', userSchema)
module.exports = User
controllers/user.js
const express = require('express')
const User = require('../models/user.model')
const router = express.Router()
router.post('/users', async (req, res) => {
// Create a new user
try {
const user = new User(req.body)
await user.save()
const token = await user.generateAuthToken()
res.status(201).send({ user, token })
} catch (error) {
res.status(400).send(error)
}
})
router.post('/users/login', async(req, res) => {
//Login a registered user
try {
const { email, password } = req.body
const user = await User.findByCredentials(email, password)
if (!user) {
return res.status(401).send({error: 'Login failed! Check authentication credentials'})
}
const token = await user.generateAuthToken()
res.send({ user, token })
} catch (error) {
res.status(400).send(error)
}
})
module.exports = router
index.js
require('dotenv').config()
const express = require('express')
const userRouter = require('./src/routers/user')
const port = process.env.PORT
require('./src/database/db')
const app = express()
app.use(express.json())
app.use(userRouter)
app.listen(port, () => {
console.log(`Server running on port ${port}`)
})
so each time i try to see if i'm signed up or not postman didn't give any response he keep saying <> and no result can someone help me please ?
Have you created " data " and " db " folder in your ' C ' drive?
Here are the steps:
Create a folder on your machine with name mongodb
Create a folder with name data in the mongodb folder
Create one more folder with name db in the data folder
For more, refer here
I have three models "userLogin.js","userDetail.js",and "userAddress.js".I want data should be stored simultaneously, if any error occurs it should rolback all the insert actions.this what I have tried. I gives me the error user is not defined . when try to fix them it gives the error "schema is not registered"
const UserLogin=require("../models/userLogin");
const UserDeatil=require("../models/userDetail");
var myModelSchema1 = require('mongoose').model('UserLogin').schema;
var myModelSchema2 = require('mongoose').model('UserDeatils').schema;
exports.user_signup = (req, res, next) => {
UserLogin.find({ email: req.body.email })
.exec()
.then(user => {
if (user.length >= 1) {
return res.status(409).json({
message: "Mail exists"
});
} else {
bcrypt.hash(req.body.password, 10, (err, hash) => {
if (err) {
return res.status(500).json({
error: err
});
} else {
const user = new UserLogin({
_id: new mongoose.Types.ObjectId(),
email: req.body.email,
password: hash,
loginDate:req.body.logindate,
});
const userdetils = new UserDeatil({
_id: new mongoose.Types.ObjectId(),
userId:result.userID,
userName:req.body.username,
dob:req.body.dob,
gender:req.body.gender,
photo: req.file? req.file.path : null,
imei:req.body.imei,
});
insertUsers();
}
});
}
});
};
async function insertUsers(){
try{
const id= transaction.insert(myModelSchema1, user);
const id1= transaction.insert(myModelSchema2, userdetils);
const final = await transaction.run();
}
catch(error){
console.error(error);
const rollbackObj = await transaction.rollback().catch(console.error);
transaction.clean();
c
}
}
first when you define your users schema the email must be uniqe wich when fails when you tries to create anothe user document with the same email,
and with this convention you can move forward like this:
const UserLogin=require("../models/userLogin");
const UserDeatil=require("../models/userDetail");
cosnt signup = async (req ,res)=>{
const { email , password ,...details} = req.body
const createdDocs = []
const hashedPwd = hash(password);
try{
const user = new UserLogin({ email , password: hashedPwd });
await user.save()
createdDocs.push(user)
const userDetails = new UserDetails({...details,userId:user._id});
await userDetails.save()
createdDocs.push(userDetails)
catch(err){
res.json({ status:false, message:err.message})
//emulates the rollback when any thing fails on the try flow
if(createdDocs.length){
const operationsToRollBack = createdDocs.map(doc=>doc.remove)
await Promise.all(operationsToRollBack)
}
}
MongoDB supports multi-document transactions starting from version 4.0.
Ideally, if you need a transactional database you would use an SQL type db.
But if you would still like to enjoy MongoDB while needing transactions, they have introduced an API for this - https://docs.mongodb.com/manual/core/transactions/