how to write custom error message in Postman using nodejs - node.js

In my case, if I unselect any field in postman, I got an error in the terminal but I want to print that error message or custom error in the postman response. how to do that?
POST method
router.post("/admin/add_profile", upload.single("image"), async (req, res) => {
try {
const send = new SomeModel({
first_name: req.body.first_name,
last_name: req.body.last_name,
phone: req.body.phone,
email: req.body.email,
image: req.file.filename,
});
send.save();
const result = await s3Uploadv2(req.files);
res.json({ status: "Everything worked as expected", result });
} catch (err) {
res.status(404).send(err.message);
}
});
schema.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const SomeModelSchema = new Schema({
first_name: {
type: String,
required: true,
},
last_name: {
type: String,
required: ["last name is required"],
},
phone: {
type: Number,
required: ["Phone number is required"],
unique: true,
validate: {
validator: (val) => {
return val.toString().length >= 10 && val.toString().length <= 12;
},
},
},
email: {
type: String,
trim: true,
lowercase: true,
unique: true,
required: ["email address is required"],
validate: (email) => {
return /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/;
},
match: [
/^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/,
"Please fill a valid email address",
],
},
image: {
data: Buffer,
contentType: String
}
});
module.exports = mongoose.model("SomeModel", SomeModelSchema);
here I unselected the first_name field but I got an error in the terminal I want to print that error or a custom error in the postman response.
error message in terminal

You should await the save() call, which returns a Promise.
You should then be able to handle the error in the catch block:
router.post('/admin/add_profile', upload.single('image'), async (req, res) => {
try {
const send = new SomeModel({
first_name: req.body.first_name,
last_name: req.body.last_name,
phone: req.body.phone,
email: req.body.email,
image: req.file.filename,
});
await send.save();
const result = await s3Uploadv2(req.files);
res.json({ status: 'Everything worked as expected', result });
} catch (error) {
if (error.name === "ValidationError") {
let errors = [];
for (const err in error.errors) {
errors.push(err.message)
}
return res.status(400).send(errors);
}
res.status(500).send('Server error');
}
});

Related

Expressjs Mongoose trying to change data value using if statement in app.post

I would like to increment points by 1000 when visits of user become 1. I am incrementing visits by 1 whenever loginUser() function gets called.
this is my async loginUser function
async function loginUser(event) {
event.preventDefault()
const response = await fetch('http://localhost:1337/api/login', {
method: 'POST',
headers:{
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
password,
}),
})
server.js
app.post('/api/login', async (req, res) => {
await User.findOneAndUpdate(
{email: req.body.email},
{$inc :{visits : 1}},
)
const isPasswordValid = await bcrypt.compare(
req.body.password,
user.password
)
if (isPasswordValid) {
const token = jwt.sign(
{
name: user.name,
email: user.email,
},
'secret123'
)
return res.json({ status: 'ok', user: token })
} else {
return res.json({ status: 'error', user: false })
}
})
user.model.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/poker')
const User = new mongoose.Schema(
{
name: { type: String, required: true },
email: { type: String, required: true, unique: true},
password: { type: String, required: true },
points: { type: Number, required: true, default: 0},
visits: { type: Number, required: true, default: 0}
},
{ collectiopn: 'user-data' }
)
const model = mongoose.model('UserData', User)
module.exports = model
I've tried to put
if (req.body.visits == 1){
await User.findOneAndUpdate(
{email: req.body.email},
{$inc :{points: 1000}},
)
}
and it returns undefined for req.body.visits
Can anyone help?
Thank you

try to get user information by populate() but return empty array with no errors

I try to make one method for signup to two types of user ' buyer and seller ' .
When I save seller , I should get all information about their ' storeinfo ' , see my updated code below .
I used populate() but I get an empty array .
Is my idea wrong ?
code for signup
exports.signupUser = async (req, res, next) => {
role = req.body.role
const user = new User(req.body)
const seller = new Seller(req.body)
try{
if(role=='seller'){
await seller.save()
await user.save()
const token = await user.generateToken()
res.status(200).send({
error: null,
apiStatus:true,
data: {user,seller ,token}
})
}
await user.save()
const token = await user.generateToken()
res.status(200).send({
error: null,
apiStatus:true,
data: {user, token}
})
}
catch(error){
res.status(400).send({
error: error.message,
apiStatus:false,
data: 'unauthorized user'
})
}
}
code for login
exports.login = async (req, res) => {
try{
const user = await User.findUserByCredentials(req.body.email, req.body.password)
const token = await user.generateToken()
console.log(user.role)
if(user.role=='seller'){
console.log(user._id)
await User.findOne({_id: user._id}).populate('storeinfo').exec(function(err, user) {
if (err) {console.log(err)}
res.status(200).send({
error: null,
apiStatus:true,
user,token
})})
}
res.status(200).send({
error: null,
apiStatus:true,
data: {user, token}
})
}
catch(error){
res.status(400).send({
error: error.message,
apiStatus:false,
data: 'Something went wrong'
})
}
}
schema user
const userSchema = new Schema({
first_name: { type: String,required:true},
last_name: { type: String,required:true},
email: { type: String, unique: true, required: true, trim: true,lowercase: true ,validate(value) {
if (!validator.isEmail(value)) throw new Error("Invalid Email"); },
},
password: { type: String,minlength: 6,required: true, trim: true, match: /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/},
role: { type: String, enum: ['admin','seller', 'user'], default: 'user' ,required: true},
mobileNumber: { type: String,default:'',trim: true,
validate(value) {
if (!validator.isMobilePhone(value, ["ar-EG"]))
throw new Error("invalid phone number");
},
},
address: {
type: String,
required: true,
trim: true
},
storeinfo:{
type: mongoose.Schema.Types.ObjectId,
ref:'Seller',
},
tokens: [{
token: {
type: String,
required: true
}
}]
}, {
timestamps: true
})
userSchema.methods.generateToken = async function(){
const user = this
const token = jwt.sign({_id: user._id.toString() , role:user.role}, process.env.JWTKEY)
user.tokens = user.tokens.concat({token})
await user.save()
return token
}
// login
userSchema.statics.findUserByCredentials = async(email, password)=>{
const user = await User.findOne({email})
if(!user) throw new Error('invalid email')
const matched = await bcrypt.compare(password, user.password)
if(!matched) throw new Error('invalid password')
return user
}
const User = mongoose.model('User', userSchema)
module.exports = User
seller schema
const SellerSchema = new Schema(
{
storeName: {
required: true,
type: String,
},
category: {
type: String,
required: true
},
image: {
type: String,
// required: true,
},
addresses:[
{
street: String,
locality: String,
aptName: String,
lat: Number,
lng: Number,
}
],
numberOfBranches: Number,
_userId:{ type: Schema.Types.ObjectId, ref: 'User'},
items: [{ type: Schema.Types.ObjectId, ref: "Item" }]
},
{ timestamps: true }
);
const Seller = mongoose.model('Seller', SellerSchema)
module.exports = Seller

how to use populate method with react and node.js?

i have two collection in my db "users" and "forms"
each user has a table of forms
i used populate method to do this and it works
this is the model of user:
const Schema = mongoose.Schema
const UserSchema = new Schema({
firstName: {
type: 'string',
required: ' Firstname is Required'
},
lastName: {
type: 'string',
required: ' lastName is Required'
},
email: {
type: 'string',
required: ' email is Required'
},
phone: {
type: 'string',
},
entrprise: {
type: 'string'
},
password: {
type: 'string',
required: ' password is Required'
},
forms: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Form"
}
]
})
const User = mongoose.model('User', UserSchema)
module.exports = User
this the model of form
const Schema = mongoose.Schema
const FormSchema = new Schema({
logo: {
type: String,
},
compagnyName: {
type: String,
},
title: {
type: String,
},
description: {
type: String,
},
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
cardQuestion: [
{
questionTitle: String,
questionType: String,
questionCourte: String,
questionLongue: String,
choixMultiple: String,
caseaCocher: String,
telechargerFichier: String,
date: Date,
heure: String,
delete: false,
obligatoire: false,
}
]
})
const Form = mongoose.model('Form', FormSchema)
module.exports = Form
and this is how i use populate method
const getUser = async (req, res) => {
try {
const { userId } = req.params;
if (!userId) return res.status(400).json({ message: "ERROR ID!" });
const result = await User
.findById(userId).populate('forms')
.exec()
return res.status(200).json({ message: "Success", result });
} catch (err) {
res.status(500).json({ message: "INTERNAL ERROR SERVER!" });
console.log(err.message);
}
};
i added a user with forms using postman with the post method
when i try to add a form with react
const response = await axios.post(`${API_URL}/form/:userId`,
{
...form,
userId: localStorage.getItem('userId')
},
{
headers: {
authorization: localStorage.getItem('userId')
}
}
i get the form with the user id like this:
{
"_id": "6022916bf1d1060f84bc17d0",
"compagnyName": "axa",
"description": "recruitement",
"userId": "60214c5ec0491fcb2d8c29e8",
"__v": 0,
"cardQuestion": []
},
i find the new form in the forms collection but when i get the user ,the forms field doesn't update (still empty if i don't add the table of forms manually)
"result": {
"forms": [],
"_id": "60214c5ec0491fcb2d8c29e8",
"firstName": "moon",
"lastName": "lea",
"email": "moon15#gmail.com",
"password": "$2b$10$bnH0cEBQKktgaKHfBac3L.xUUNEYt9HaqKdLKxLOERrHPG4MVPPFS",
"phone": "087654266377",
"__v": 0
}
}
this is how i add a user
const register = async (req, res) => {
try {
const { firstName, lastName, email, phone, password, forms } = req.body
if (!firstName || !lastName || !email || !phone || !password)
return res.status(400).json({ message: 'ERROR!' })
//CHECKING EXISTING USER
const found = await User.findOne({ email })
console.log(found)
if (found) return res.status(400).json({ message: 'Email already exist' })
console.log(found)
//HASHING THE PASSWORD
const hashPassword = await bcrypt.hash(password, saltRounds)
console.log(hashPassword)
//CREATING THE NEW USER
const newUser = new User()
newUser.firstName = firstName
newUser.lastName = lastName
newUser.email = email
newUser.password = hashPassword
if (phone) newUser.phone = phone
if (forms) newUser.forms = forms
console.log('i')
//SAVING THE NEW USER
const result = await newUser.save()
console.log(result)
if (!result) return res.status(400).json({ message: 'failed to create user' })
can someone help?
maybe you have to change .populate('forms') in getUser to .populate('form')
i think it save it in singular shape

mongoose with rxjs - can´t catch error on promise resolve

i´m using mongoose in my node.js - express. In my schema model i´m using the package mongoose-unique-validator to check that user email is unique, if the email already exist i would get and error ValidationError: User validation failed: email: Error, expected "email" to be unique. Value: "example#example.com" (which is fine). i decide to turn my promises from mongoose to rxjs observables this way:
controller.ts
creatUser(req: Request, res: Response, next: NextFunction) {
from(bcrypt.hash(req.body.password, 10))
.pipe(
mergeMap((hash) => {
const avatartPath = this.utilities.generateImgPath(req);
const user = this.userAdatper.userAdatper(req.body, { password: hash, avatar: avatartPath });
return of(new User(user).save()).pipe(catchError((error) => of(error)));
})
)
.subscribe(
(user) => {
console.log() // Promise is resolve here on the validation error return an empty object
res.status(201).send(user);
},
(err) => {
console.log(err);
res.status(500);
const error = new Error(`Internal Server Error - ${req.originalUrl}`);
next(error);
}
);
}
**Schema**
const UserSchema = new Schema({
user_rol: {
type: String,
default: 'subscriber',
},
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
requiered: true,
},
fullName: {
type: String,
requiered: true,
},
email: {
type: String,
requiered: true,
unique: true,
},
password: {
type: String,
requiered: true,
},
avatar: {
type: String,
requiered: true,
},
favorites: [
{
type: [Schema.Types.ObjectId],
ref: 'ArcadeItems',
},
],
updatedOn: {
type: Date,
required: true,
},
created: {
type: Date,
default: Date.now,
},
});
UserSchema.plugin(uniqueValidator);
but for some reason if the promise fail, it resolve on the success callback after subscription returning and empty object and no the error callback, try to implement catchError() from rxjs operators but no success.
Replace of(new User(user)...) for from(new User(user)...) and on cathError() return throwError(error)
creatUser(req: Request, res: Response, next: NextFunction) {
from(bcrypt.hash(req.body.password, 10))
.pipe(
mergeMap((hash) => {
const avatartPath = this.utilities.generateImgPath(req);
const user = this.userAdatper.userAdatper(req.body, { password: hash, avatar: avatartPath });
return from(new User(user).save()).pipe(catchError((error) => throwError(error)));
})
)
.subscribe(
(user) => {
console.log() // Promise is resolve here on the validation error return an empty object
res.status(201).send(user);
},
(err) => {
console.log(err);
res.status(500);
const error = new Error(`Internal Server Error - ${req.originalUrl}`);
next(error);
}
);
}

Routing in NodeJs

I am working on an eCommerce application, and I am trying to save users in my database but when I hit the API in the postmen then instead of :
res.json({
name: user.name,
email: user.email,
id: user._id
});
});
**instead of this code following code is running
user.save((err, user) => {
if (err) {
return res.status(400).json({
err: "NOT able to save user in DB"
});
}
//the complete code of my "auth.js" file is as following:
const User = require("../models/user");
exports.signup = (req, res) => {
const user = new User(req.body);
user.save((err, user) => {
if (err) {
return res.status(400).json({
err: "NOT able to save user in DB"
});
}
res.json({
name: user.name,
email: user.email,
id: user._id
});
});
};
exports.signout = (req, res) => {
res.json({
message: "User signout"
});
};
///and the complete code of my user model file is as following:
var mongoose = require("mongoose");
const crypto = require("crypto");
const uuidv1 = require("uuid/v1");
var userSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
maxlength: 32,
trim: true
},
lastname: {
type: String,
maxlength: 32,
trim: true
},
email: {
type: String,
trim: true,
required: true,
unique: true
},
userinfo: {
type: String,
trim: true
},
encry_password: {
type: String,
required: true
},
salt: String,
role: {
type: Number,
default: 0
},
purchases: {
type: Array,
default: []
}
},
{ timestamps: true }
);
userSchema
.virtual("password")
.set(function(password) {
this._password = password;
this.salt = uuidv1();
this.encry_password = this.securePassword(password);
})
.get(function() {
return this._password;
});
userSchema.methods = {
autheticate: function(plainpassword) {
return this.securePassword(plainpassword) === this.encry_password;
},
securePassword: function(plainpassword) {
if (!plainpassword) return "";
try {
return crypto
.createHmac("sha256", this.salt)
.update(plainpassword)
.digest("hex");
} catch (err) {
return "";
}
}
};
module.exports = mongoose.model("User", userSchema);
SO please anyone tell me how to solve this problem while hiting this code to api mongo shell is also opend and mean while i also keep ROBO3T connected.

Resources