mongoose: validation error on post request - mongodb

I'm trying to save a new use in mongodb with mongoose, but I am getting ValidationError: "err": "User validation failed:Path 'email' is required., Path 'fname' is required., Path 'username' is required phone: Path phone .despite I make all the data in the body of the post request so:
this is the userModel:
import mongoose from "mongoose";
const userSchema = new mongoose.Schema({
_id: {type: Number},
name: {type: String, required: true},
fname: {type: String, required: true},
phone: {type: String, required: true},
email: {type: String, required: true, unique: true},
password: {type: String, required: false},
image: {type: String, required: false},
isAdmin: {type: Boolean, default: false, required: true},
}, {
timeStamps: true
});
const User = mongoose.model('User', userSchema);
export default User;
this is the userRouter.js:
import express from "express";
import data from '../../data.js';
import User from "../userModel.js";
import expressAsyncHandler from "express-async-handler";
import {generateToken} from "../../utils.js";
import bcrypt from "bcryptjs";
const userRouter = express.Router();
let allUsers = data.users;
userRouter.get("/seed", expressAsyncHandler(async(req, res)=>{
//await User.remove({});
const createdUsers = await User.insertMany(allUsers);
res.send({createdUsers});
}));
userRouter.post("/register", expressAsyncHandler(async(req, res)=> {
//await User.remove({});
const user = new User({
name: req.body.name,
fname: req.body.fname,
phone: req.body.phone,
email: req.body.email,
});
const createdUser = await user.save();
res.send({
_id: createdUser._id,
name: createdUser.name,
fname: createdUser.fname,
phone: createdUser.phone,
email: createdUser.email,
token: generateToken(createdUser)
})
}))
export default userRouter;

Related

Mongoose Nested Schema - required fields inside array field

I have following mongoose schema -
const UserSchema = new mongoose.Schema({
name: {type: String, required: true, trim: true},
email: {type: String, required: true, trim: true},
password: {type: String, required: true, trim: true},
addresses: [{
type: {type: String, required: true, trim: true},
pinCode: {type: String, required: true, trim: true},
city: {type: String, required: true, trim: true},
state: {type: String, required: true, trim: true},
landmark: {type: String, required: false, trim: true},
}]
})
only name, email and password are required for registration. User can have more than one address , and each address has some required fields like in flipkart.com/account/addresses user's account page.
Each address will be stored in addresses array field in mongodb database.
I want to keep addresses array [ ] when user register. address are only provided through user's account page web page.
But I am getting ValidatorError because schema of doc inside addresses array having required fields.
when user register -
{
name: 'rahul',
email: 'rahul#example.com',
password: 'pass123',
addresses: []
}
user is already registered, and then add address
{
name: 'rahul',
email: 'rahul#example.com',
password: 'pass123',
addresses: [
{
type: 'home',
pinCode: '111222',
city: 'city1',
state: 'state1'
},
{
type: 'work',
pinCode: '333444',
city: 'city2',
state: 'state2',
landmark: 'landmark2'
}
]
}
How to achieve above ??
Any help would be appreciated.
You just have to remove required:true field from address array not even required:false.
Just type and trim will the job and required is false by default so you dont have to include it.
I was doing this -
const userDoc = new UserModel({
name: nm,
email: em,
password: pass,
addresses: []
})
Not passing addresses: [], prevent error ValidatorError
const userDoc = new UserModel({
name: nm,
email: em,
password: pass
})
Try the below code. Hope this will help you.
const ToySchema = new mongoose.Schema({ name: String });
const ToyBoxSchema = new mongoose.Schema({
toys: [ToySchema],
bucketName: String,
numToys: Number
});
const ToyBox = mongoose.model('ToyBox', ToyBoxSchema);
var toyBoxData = {
toys : [
{ name : "Dummy Toy 1"},
{ name : "Dummy Toy 2"},
{ name : "Dummy Toy 3"},
],
bucketName: "My Toy Bucket",
numToys: 3
}
var toyBucket = new ToyBox(toyBoxData);
toyBucket.save( (err: any)=> {
console.log(err);
})
And when you will run the above code, you will be able to see a collection and document like this in your DB, as in the below screenshot.
Hope this will help you. For more information please visit this mongoose documentation link.

How to create an array of objects with default values?

how to create an array of objects with default values?
const schema = new mongoose.Schema({
login: {type: String, unique: true, required: true},
password: {type: String, required: true},
chatlist: [
{
channelname: {type: String, default: "frontend"},
channelid: {type: String, default: "619a6bfe5b0931f1e5dbaf2c"}
},
{
channelname: {type: String, default: "backend"},
channelid: {type: String, default: "619a71002954ba23a951bb8f"}
},
{
channelname: {type: String, default: "devops"},
channelid: {type: String, default: "619d69c190a85a40893b6522"}
},
]
})
this code above does not work
when a new user register i want to add a default chats to his profile
next thing is the user must be able to add/remove chats from the database
how should i do this? do the chats need to be an objects or documents?
const schema = new mongoose.Schema({
chatlist: {
type: Array,
defualt: []
}
})
so to have a structure in the array I personally would make the request correct using error handling.
for more information visit this site
didnt find any good solution so i just did this
const schema = new mongoose.Schema({
login: {type: String, unique: true, required: true},
password: {type: String, required: true},
chatlist: [{
channelname: String,
channelid: String
}]
})
const user = await MONGO_user.create({
login: login,
password: hashPassword,
})
user.chatlist.push(
{
channelname: "frontend",
channelid: "619a6bfe5b0931f1e5dbaf2c"
}, {
channelname: "backend",
channelid: "619a71002954ba23a951bb8f"
}, {
channelname: "devops",
channelid: "619d69c190a85a40893b6522"
})
await user.save()

How to Populate CartItem schema product details into Order Schema using mongoose

I want to populate the details of products in my order. Currently it is only adding product id inside the products array. I tried a couple of methods but none seems to work.
import mongoose from 'mongoose'
const CartItemSchema = new mongoose.Schema({
product: {type: mongoose.Schema.ObjectId, ref: 'Product'},
quantity: Number,
shop: {type: mongoose.Schema.ObjectId, ref: 'Shop'},
status: {type: String,
default: 'Not processed',
enum: ['Not processed' , 'Processing', 'Shipped', 'Delivered', 'Cancelled']}
})
const CartItem = mongoose.model('CartItem', CartItemSchema)
const OrderSchema = new mongoose.Schema({
products: [CartItemSchema],
customer_name: {
type: String,
trim: true,
required: 'Name is required'
},
customer_email: {
type: String,
trim: true,
match: [/.+\#.+\..+/, 'Please fill a valid email address'],
required: 'Email is required'
},
delivery_address: {
street: {type: String, required: 'Street is required'},
city: {type: String, required: 'City is required'},
state: {type: String},
zipcode: {type: String, required: 'Zip Code is required'},
country: {type: String, required: 'Country is required'}
},
payment_id: {},
updated: Date,
created: {
type: Date,
default: Date.now
},
user: {type: mongoose.Schema.ObjectId, ref: 'User'}
})
const Order = mongoose.model('Order', OrderSchema)
export {Order, CartItem}
I tried doing this:
const create = async (req, res) => {
try {
req.body.order.user = req.profile;
console.log(req);
let order = new Order(req.body.order);
let neworder = await Order.findById(order._id)
.populate("products.product", "name price")
.populate("products.shop", "name")
.exec();
// console.log(order);
let result = await order.save();
sendMail(order);
res.status(200).json(result);
} catch (err) {
return res.status(400).json({
error: errorHandler.getErrorMessage(err),
});
}
};
Also tried using this for poulating the product details but doesnt seem to work!
Order.findById(order._id).populate({ path: "products.product", select: "_id name price" })

How to make an update on field depending on linked document field

I'm trying to conditionally update a field in a document but I need to know the value of an other field in a linked document. I'm struggling to explain my problem so i will give you my code and try to explain what I'm trying to do.
I got a route to update my 'workstation' collection
router.post("/workstation/update/:id", (req, res, next) => {
const id = req.params.id;
const previousWorkstation = req.body.previous;
const updatedWorkstation = req.body.updated;
const {errors, isValid} = validateWorkstation(updatedWorkstation);
if(!isValid){
return res.status(422).json(errors);
}
Workstation.findByIdAndUpdate(mongoose.Types.ObjectId(id), updatedWorkstation, (err, workstation) => {
if(err) return;
NonConformity.updateMany({workstation: previousWorkstation.name, line: previousWorkstation.line}, {$set:{workstation: updatedWorkstation.name}}, (err) => {
if(err) return;
Rework.updateMany({workstation: previousWorkstation.name}, {$set:{workstation: updatedWorkstation.name}}, (err) => {
if(err) return;
res.send(200);
})
})
})
});
My problem is I need to update rework depending on the line too, and not only the workstation name ! Here are my schemas
// WORKSTATION SCHEMA
const mongoose = require('mongoose');
const WorkstationSchema = mongoose.Schema({
name: {type:String, required: true},
line: {type:String, required: true}
})
const Workstation = mongoose.model('workstations', WorkstationSchema);
module.exports = Workstation;
// REWORK SCHEMA
const mongoose = require('mongoose');
const ReworkSchema = mongoose.Schema({
nonConformity_id: {type:String, required: true},
operator: {type:String, required: true},
fin: {type:String, required: true},
workstation: {type:String, required: false},
code: {type:String, required: true},
declination: {type:String, required: true},
description: {type:String, required: true},
advice: {type:String, required: false},
pps: {type: String, required: false},
quantity: {type:Number, required: true},
reworked: {type:Boolean, default: false, required: true},
verified: {type:Boolean, default: false, required: true},
})
const Rework = mongoose.model('nonConformities.reworks', ReworkSchema);
module.exports = Rework;
// NON CONFORMITY
const mongoose = require('mongoose');
const NonConformitySchema = mongoose.Schema({
number: {type: String, unique: true, required: true, dropDups: true},
line: {type: String, required: true},
product: {type: String, required: true},
workstation: {type: String, required: true},
msn: {type: String, required: true},
date: {type: String, required: true},
type: {type: String, required: true},
})
const NonConformity = mongoose.model('nonConformities', NonConformitySchema);
module.exports = NonConformity;
My question is : Is it possible to update my workstation name in the rework collection depending on the line name of the linked non conformity id in the rework schema ?
Sorry if my english is bad, i can try to reformulate if you don't understand my question.
Thanks in advance !

Not sure if the token is being correctly and safely, mongoose schema

Hey guys here is my mongoose schema with a way to create a user token that will be included in a password reset link, I was just wondering if it looked right? Also, not sure how to exactly call a new token, after the User has been created, will a User.save or User.findAndUpdate and then include the token work in the route file? Also, what do I insert inside the token field as a value that will draw from the token encrypted here?
Here is the file:
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ObjectId = mongoose.Schema.Types.ObjectId,
bcrypt = require('bcrypt-nodejs'),
SALT_WORK_FACTOR = 10;
var crypto = require('crypto');
var UserToken;
var UserSchema = new Schema({
email: { type: String, required: true, lowercase:true, index: { unique: true } },
password: { type: String, required: true },
firstName: {type: String, required: true},
lastName: {type: String, required: true},
phone: {type: Number, required: true},
birthday: {type: Date, required: true},
friendRequest: {type: Object},
notifications: {type: Object},
friend: {type: Object},
date_created: {type: Date},
token: {type: String}
}, {collection: "users"});
UserSchema.statics.new = function(_id, fn) {
var user = new UserToken();
crypto.randomBytes(48, function(ex, buff) {
var token = buff.toString('based64').replace(/\//g, '_').replace(/\+/g, '-');
user.token = _id + '|' + token.toString().slice(1,24);
user._id = _id;
user.save(fn);
});
};
module.exports = mongoose.model('User', UserSchema);