I am new to node, express wanted a help regarding validation.I am able to validate the data corresponded to post method but for put method the data is not able to get validated.What should be done for the data to get validated in put method?
Below is the user Model
const userSchema = new Schema({
name: {
type: String,
minlength: 3,
required: true,
validate:{
validator:function(value){
return value.length >=3
},
msg:function(){
return 'name is less than 3 characters'
}
}
},
const User = mongoose.model('User', userSchema)
module.exports = User
Below is the controller for user
const express = require('express')
const router = express.Router()
const Customers = require('../model/customers')
router.get('/', (req, res) => {
Customers.find()
.then((customer) => {
res.json(customer)
console.log(customer)
})
.catch(err => res.send(err))
})
router.post('/', async (req, res) => {
let customerData = new Customers({
name: req.body.name,
email: req.body.email,
mobile: req.body.mobile
})
await customerData.save()
.then((customer) => {
res.json(customer)
console.log('customer is....', customer)
})
.catch(err => res.send(err))
})
router.put('/:id', async (req, res) => {
let apiId = req.params.id
const customerData = await Customers.findByIdAndUpdate(apiId,
{
name: req.body.name,
email: req.body.email,
mobile: req.body.mobile
})
if (customerData) {
res.json(Object.assign(customerData, req.body))
}
else {
res.status(404).send('Url did not respond')
}
})
router.delete('/:id', async (req, res) => {
let apiId = req.params.id
const customerData = await Customers.findByIdAndRemove(apiId)
if (customerData) {
res.send(customerData)
}
else {
res.status(404).send('Url did not respond')
}
})
module.exports = { customerController: router }
As per mongoose docs
Mongoose also supports validation for update(), updateOne(),
updateMany(), and findOneAndUpdate() operations. Update validators are
off by default - you need to specify the runValidators option
So you have to set runValidators: true
Customers.findByIdAndUpdate(apiId,
{
name: req.body.name,
email: req.body.email,
mobile: req.body.mobile
}, { runValidators: true } )
Related
I'm trying to be able to delete a user if they choose to delete their account. I'm not sure how it's properly done. Here's the code for the delete function. I've looked at other StackOverflow solutions but I haven't been able to grasp the concept just yet. can anyone help?
const { validationResult } = require('express-validator')
const User = require('../modelSchema/User')
const mongo = require('mongodb')
const signUp = (req, res) => {
const errors = validationResult(req)
if(!errors.isEmpty()) return res.status(400).json({ errors: errors.array()})
//new instance of user
const user = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password })
//save the user
user.save()
.then(data => {
res.json(data)
res.send('User added successfully!')
console.log(data)
})
.catch(err => {
res.status(400).json(err)
})
}
const deleteUser = (req, res) => {
let id = req.params.id;
User.get().createCollection('user', function ( col) {
col.deleteOne({_id: new mongo.ObjectId(id)});
});
res.json({ success: id })
res.send('User Deleted Successfully!')
.catch(err => {
res.status(400).json(err)
})
}
module.exports = { signUp, deleteUser }
here are the routes that I'm using
const express = require('express');
const { check } = require('express-validator')
const { signUp, deleteUser } = require('../controllers/users');
const router = express.Router();
router.post('/signup', [
check('name', 'Please Enter your Name').not().isEmpty(),
check('email', 'Please Enter your Email').isEmail(),
check('password', 'Please Enter your Password').isLength({ minLength: 6})
], signUp)
router.delete('/delete/:id', deleteUser)
module.exports = router;
and here's my schema
const mongoose = require('mongoose');
let userSchema = new mongoose.Schema({
name: { type: 'string', required: true},
email: { type: 'string', required: true},
password: { type: 'string', required: true},
date: { type: Date, default: Date.now}
})
module.exports = mongoose.model('user', userSchema)
Update your delete function as below
const deleteUser = async (req, res) => {
const { id } = req.params;
const user = await User.findByIdAndDelete(id);
if (!user) {
return res.status(400).json("User not found");
}
res.status(200).json("User deleted successfully");
};
findByIdAndDelete takes an ObjectId of a user to be deleted. If the user exist, it'll delete the user and return user document, else return null;
*I can create new account and also i can login but when i am going to logout that time i will logout but if i am try to login with same email and password but i cannot able to login it is showing me jsonwebtoken error -> {"name":"JsonWebTokenError","message":"jwt must be provided"} *
register.js
This is my register.js file code
app.get("/register", (req, res) => {
// res.send('Hello Arunesh')
res.render("register");
});
app.post("/register", async (req, res) => {
try {
const password = req.body.password;
const cPassword = req.body.cPassword;
if (password === cPassword) {
const registerData = new Register({
firstName: req.body.firstName,
lastName: req.body.lastName,
phone: req.body.phone,
gender: req.body.gender,
email: req.body.email,
age: req.body.age,
password: req.body.password,
confirmPassword: req.body.cPassword,
});
const token = await registerData.generateAuthToken();
console.log('Register Token : ',token);
res.cookie('jwt', token,{
httpOnly:true
})
const register = await registerData.save();
console.log(register);
res.status(201).render("index");
} else {
res.send("Password are not match");
}
} catch (e) {
res.status(400).send(e);
}
});
login.js
app.get("/login", (req, res) => {
res.render("login");
});
app.post("/login", auth,async (req, res) => {
try {
const email = req.body.email;
const password = req.body.password;
const userEmail = await Register.findOne({ email: email });
const isMatch = await bcrypt.compare(password, userEmail.password);
const token = await userEmail.generateAuthToken();
res.cookie('jwt', token,{
expires:new Date(Date.now()+30000000),
httpOnly:true
})
console.log('Login Token : ',token);
console.log(isMatch);
if (isMatch) {
res.status(201).render("index");
} else {
res.send("Invalid password or email");
}
} catch (e) {
res.status(400).send(e);
}
});
Logout.js
app.get('/logout', auth,async (req, res)=>{
try{
// console.log(req.user);
// Logout for single user
req.user.tokens = req.user.tokens.filter((authToken)=>{
return authToken.token != req.token;
})
// logout from all device
// req.user.tokens = [];
res.clearCookie("jwt");
await req.user.save();
res.render('login');
}catch(e){
console.log(e);
}
})
auth.js
const jwt = require('jsonwebtoken');
const Register = require('../models/registers');
const auth = async (req, res, next)=>{
try{
const token = req.cookies.jwt;
const verifyUser = jwt.verify(token, process.env.SECRET_KEY);
const user = await Register.findOne({_id:verifyUser._id, 'tokens.token':token})
req.token = token;
req.user = user;
next()
}catch(e){
res.send(e)
}
}
module.exports = auth;
**
generateAuthToken
**
registerSchema.methods.generateAuthToken = async function () {
try {
const token = jwt.sign({ _id: this._id.toString() },process.env.SECRET_KEY);
this.tokens = this.tokens.concat({token:token})
await this.save();
return token;
} catch (e) {
console.log(e);
}
};
**
Schema
**
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const registerSchema = new mongoose.Schema({
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
phone: {
type: Number,
required: true,
unique: true,
},
gender: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
age: {
type: Number,
required: true,
},
password: {
type: String,
required: true,
},
confirmPassword: {
type: String,
required: true,
},
tokens: [
{
token: {
type: String,
required: true,
},
},
],
});
/********************************************
* Generate Token
********************************************/
registerSchema.methods.generateAuthToken = async function () {
try {
const token = jwt.sign({ _id: this._id.toString() },process.env.SECRET_KEY);
this.tokens = this.tokens.concat({token:token})
await this.save();
return token;
} catch (e) {
console.log(e);
}
};
/********************************************
* Password Hash
********************************************/
registerSchema.pre("save", async function (next) {
if (this.isModified("password")) {
this.password = await bcrypt.hash(this.password, 10);
this.confirmPassword = await bcrypt.hash(this.password, 10);
}
next();
});
const Register = new mongoose.model("Register", registerSchema);
module.exports = Register;
you use auth middleware in /login route, this error happens when the coming token is null or empty ,remove auth middleware from the route like this, I hope the problem is solved with my answer
app.post("/login" , async (req, res) => {...
I have a form with the input fields "firstName", "lastName" and "assetTag". I want to submit that form and post all that data plus one additional field called "modelType". The data from the modelType field is from the function call si.system() but i'm not sure how to pass that into the Model because it's a promise.
How can I pass the data from my console.log(data.model) into my formData?
app.js post request:
app.post('/', (req, res) => {
si.system()
.then(data => console.log(data.model))
.catch(error => console.error(error))
const formData = {
firstName: req.body.firstName,
lastName: req.body.lastName,
assetTag: parseInt(req.body.assetTag)
}
const system = new System(formData);
system.save()
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
});
});
Model:
const mongoose = require('mongoose');
var SystemSchema = new mongoose.Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
assetTag: {
type: Number,
required: true
},
modelType: {
type: String,
required: true
}
});
module.exports = mongoose.model('System', SystemSchema);
if you are talking about getting that value out of the promise you need to look into async / await.
here's the code
app.post('/', async (req, res) => {
let data = await si.system();
const formData = {
firstName: req.body.firstName,
lastName: req.body.lastName,
modelType: data.model,
assetTag: parseInt(req.body.assetTag)
}
const system = new System(formData);
system.save()
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
});
});
I working on Mongoose and Express project where by I have 3 models: User, Album and Purchase. The purchase model references the user and album. I am creating a POST endpoint where by I can make a purchase and then retrieve the data as well as the user and album relations which should be populated with their data, but I am stuck.
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
// TODO: Define Schema
name: {
type: String,
required: true
}
})
var User = mongoose.model('User', userSchema)
var albumSchema = mongoose.Schema({
// TODO: Define Schema
title: {
type: String,
required: true
},
performer: {
type: String,
required: true
},
cost: {
type: Number,
required: true
}
})
var Album = mongoose.model('Album', albumSchema);
var puchaseSchema = mongoose.Schema({
// TODO: Define Schema
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Album'
},
album: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
})
var Purchase = mongoose.model('Purchase', puchaseSchema);
app.use(bodyParser.json());
app.listen(3000);
// TODO: GET /albums
app.get('/albums', (req,res) => {
Album.find()
.then((response) => {
res.json({data: response})
})
.catch(err => {
res.json({error: err})
})
})
// TODO: GET /albums/:id
app.get('/albums/:id', (req,res) => {
Album.findById(req.params.id)
.then(response => {
res.json({data: response})
.catch(err => {
res.json({Error: err})
})
})
})
// TODO: POST /albums
app.post('/albums', (req,res) => {
const newPost = Album({
title: req.body.title,
performer: req.body.performer,
cost: req.body.cost
})
newPost.save(err => {
if(err)
res.json({error: err})
})
.then(data => {
res.json({data: data})
})
})
// TODO: PUT /albums/:id
app.put('/albums/:id', (req,res) => {
Album.findByIdAndUpdate(req.params.id, req.body, {new: true},
(err, album) =>{
if(err) return res.status(500).send(err)
return res.json({data: album})
})
})
// TODO: DELETE /albums/:id
app.delete('/albums/:id', (req,res) => {
const id = req.params.id
Album.findById(id)
.then(docs => {
docs.remove()
res.status(204)
.json({data:docs})
})
})
// TODO: POST /purchases
app.post('/purchases', (req,res) => {
})```
This might help you. Look into mongoose's populate method.
app.post('/purchases', (req,res) => {
const user = req.body.userId;
const album = req.body.albumId;
const newPurchase = new Purchase({
user: user,
album: album
});
newPurchase.save().then((purchase) => {
Purchase.findById(purchase.id).populate('user').populate('album').then((purchaseData) => {
return res.json({purchaseData});
}).catch(e => {
console.log(e);
});
}).catch(e => {
console.log(e);
});
})
Here's an alternative for populating after saving the document.
app.post('/purchases', (req,res) => {
const user = req.body.userId;
const album = req.body.albumId;
const newPurchase = new Purchase({
user: user,
album: album
});
newPurchase.save().then((purchase) => {
Purchase.populate(purchase, [{path: 'user'}, {path: 'album'}], (err, data) => {
if(err) {
return res.json(e);
}
return res.json(data);
});
}).catch(e => {
console.log(e);
});
}
)
As mentioned here: https://mongoosejs.com/docs/api.html#model_Model.populate
I am writing a multi-user online dictionary. I want to implement a leadership board, e.i. "score" attribute increases, as soon as a user adds a word. I have a rough idea on how to do it, and tried one solution, however it does not work. Could you please guide me?
Word API route
const express = require('express');
const router = express.Router();
const Word = require('../../models/Word');
const User = require('../../models/User');
const validateWordInput = require('../../validation/word');
const passport = require('passport');
// #route POST api/words
// #desc Add words to profile
// #access Private
router.post(
'/',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const { errors, isValid } = validateWordInput(req.body);
// Check validation
if (!isValid) {
// Return any errors
return res.status(400).json(errors);
}
Word.find({}).then(word => {
if (
word.filter(
wrd =>
wrd.ugrWordCyr.toString().toLowerCase() ===
req.body.ugrWordCyr.toLowerCase()
).length !== 0
) {
return res
.status(404)
.json({ wordalreadyexists: 'Word already exists' });
} else {
const newWord = new Word({
user: req.user.id,
ugrWordCyr: req.body.ugrWordCyr,
rusTranslation: req.body.rusTranslation,
example: req.body.example,
exampleTranslation: req.body.exampleTranslation,
origin: req.body.origin,
sphere: req.body.sphere,
lexis: req.body.lexis,
grammar: req.body.grammar,
partOfSpeech: req.body.partOfSpeech,
style: req.body.style
});
newWord.save().then(word => res.json(word));
User.update(
{ _id: '5cf0cb78b3105d1ba8e30331' },
{ $inc: { score: 1 } }
);
}
});
}
);
User model
This is where a score attribute is located
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create schema
const userSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
score: {
type: Number,
default: 0
},
avatar: {
type: String
},
date: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model('users', userSchema);
After successfully saving the word, we should update the user count
To update the respective user's score you can do the following:
newWord.save().then((word) => {
//now update user model
User.findOne({ _id: req.user.id }) <-- or an id you would like
.then((foundUser) => {
foundUser.score = foundUser.score + 1
foundUser.save()
.then((savedUser) => {
res.json({ word, savedUser })
})
.catch((err) => {
return res.status(400).json({ error: "could not add score"})
})
})
.catch((err) => {
return res.status(400).json({ error: "could not find user"})
})
})