Nodejs saving to mongoDB - node.js

I want to save data to database but i dont know how to do it in this case.
userModel.js
const userSchema = new mongoose.Schema({
email: {
type: String,
unique: true
},
password: String,
passwordResetToken: String,
passwordResetExpires: Date,
profile: {
firstname: String,
lastname: String,
gender: String,
status: String,
location: String,
website: String,
picture: String
}
});
Signup.js
const user = new User({
firstname: req.body.firstname,
lastname: req.body.lastname,
location: req.body.location,
status: 0,
email: req.body.email,
password: req.body.password
});
Problem is that those things in profile wont save and i dont know how to edit that signup.js to make it work. Something like profile.firstname: req.body.firstname does not work.

const user = new User({
profile: {
firstname: req.body.firstname,
lastname: req.body.lastname,
location: req.body.location,
status: 0,
},
email: req.body.email,
password: req.body.password
});
From schema (userModel.js), we need update with profile structure

You need to save like this in signUp.js
const user = new User({
profile :{
firstname: req.body.firstname,
lastname: req.body.lastname,
location: req.body.location,
status: 0
},
email: req.body.email,
password: req.body.password
});
As firstname, lastname, location and status are part of the profile object.

Related

How to check confirm password with zod

How do I check for confirm password with zod?. I want to validate for confirm password with Zod. I want Zod to compare my password with comparePassword
export const registerUSerSchema = z.object({
firstName: z.string(),
lastName: z.string(),
userName: z.string(),
email: z.string().email(),
phone: z.string().transform(data => Number(data)),
password: z.string().min(4),
confirmPassword: z.string().min(4),
avatar: z.string().optional(),
isVerified: z.boolean().optional()
})
You can achieve this by tacking on a superRefine
export const registerUserSchema = z.object({
firstName: z.string(),
lastName: z.string(),
userName: z.string(),
email: z.string().email(),
phone: z.string().transform(data => Number(data)),
password: z.string().min(4),
confirmPassword: z.string().min(4),
avatar: z.string().optional(),
isVerified: z.boolean().optional()
}).superRefine(({ confirmPassword, password }, ctx) => {
if (confirmPassword !== password) {
ctx.addIssue({
code: "custom",
message: "The passwords did not match"
});
}
});
If the passwords fail to parse for the base reason (not at least 4 characters) then that error will come through, but if the whole base object succeeds to parse, then the super refine check will happen.
I have like this:
const validationSchema = z
.object({
name: string().min(1, { message: "Name is required" }), // pass custom message
email: string().email(),
website: string().optional(),
country: string(),
password: string(),
confirm: string(),
})
.refine((data) => data.password === data.confirm, {
message: "Passwords don't match",
path: ["confirm"],
});
I am using React Hook Form.
Here are some docs, I copy and pasted for you, so you can see how it works: https://docs.google.com/document/d/1jqTth88I-D0-qzq34B4sUGbp8wGmExS7kpc78QA_4sk/edit?usp=sharing

mongoose put does not check for required field

I am making nodejs API and I have a user model. Some fields are required. When trigger post it will tell me that some fields required so no save will be done, but when I do it with put it will replace it even if validation is wrong, or even if there is a required field and is missing, but duplicates run good.
this is the model of user
const mongoose = require('mongoose');
const validator = require('validator');
const userSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
firstName: {
type: String,
required: [true, 'the firstName is missing'],
validate: [(val) => validator.isAlpha(val, ['fr-FR']), 'not valid first name'],
},
lastName: {
type: String,
required: [true, 'the lastName is missing'],
validate: [(val) => validator.isAlpha(val, ['fr-FR']), 'not valid last name'],
},
phoneNumber: {
type: String,
required: [true, 'the phoneNumber is missing'],
unique: [true, 'phoneNumber already in use'],
validate: [(val) => validator.isMobilePhone(val,['ar-DZ']), 'not valid phone number'],
},
email : {
type: String,
required: [true, 'the email is missing'],
unique: [true, 'email already in use'],
validate: [validator.isEmail, 'not valid email'],
},
role: {
type : String,
"enum" : ['teacher', 'student'],
required : [true, 'the user `s role is missing'],
}
});
module.exports = mongoose.model('User', userSchema);
this is where I handle put
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const User = require('../../../../models/user');
router.put('/', (req, res) => {
//get the new user object
const userId = req.body.userId;
User.replaceOne({
_id: userId
},
{
_id: userId,
firstName: req.body.firstName,
lastName: req.body.lastName,
phoneNumber: req.body.phoneNumber,
email: req.body.email,
role: req.body.role
})
.exec()
.then(response => {
res.status(200).json(response);
})
.catch(err => console.log(err));
});
module.exports = router;
so I tried to test those, by postman, I wanted from mongoose to do that automatically, I thought about splitting it and redirect it to delete then post, but i will need to do the checking first, or just do the checking manually, and because am using api, I don't want to use the patch method so I don't track the user for what changes he did in the front end.
You can, instead of replaceOne() use updateOne() or findOneAndUpdate() with turned on validators (as they are of by default), like so:
User.updateOne({_id: userId},
{
_id: userId,
firstName: req.body.firstName,
lastName: req.body.lastName,
phoneNumber: req.body.phoneNumber,
email: req.body.email,
role: req.body.role
},
{runValidators: true})
.then(response => {
res.status(200).json(response);
})
.catch(err => console.log(err));
Or you can call the validate() on the new instance of the model and if it is valid continue with update logic, e.g.
let user = new User({_id: userId,
firstName: req.body.firstName,
lastName: req.body.lastName,
phoneNumber: req.body.phoneNumber,
email: req.body.email,
role: req.body.role});
user.validate()
.then(() => {
// update logic
})
.catch((err) => {
// handle error
})
Look for more information on Mongoose validation with update.

Accessing JSON objects in this format

const login = await Signupdetails.find(req.body);
login =
[
{
PersonalInformation: {
firstName: 'aravind',
lastName: 'john',
phoneNumber: 9736363777,
DOB: 1999-07-08T18:30:00.000Z
},
Address: {
street: 'pillai',
city: 'Chennai',
pincode: 89997,
state: 'kerala',
country: 'India'
},
password: 'social',
_id: 607804f65c166c32144ae227,
email: 'hari#gmail.com',
userName: 'hari',
__v: 0
}
]
If I try using login.userName ,its showing undefined . This is a part of my Get API request . I used node.js and mongodb
You have a list, if you want login to be an Object, remove '[' characters:
login =
{
PersonalInformation: {
firstName: 'aravind',
lastName: 'john',
phoneNumber: 9736363777,
DOB: 1999-07-08T18:30:00.000Z
},
Address: {
street: 'pillai',
city: 'Chennai',
pincode: 89997,
state: 'kerala',
country: 'India'
},
password: 'social',
_id: 607804f65c166c32144ae227,
email: 'hari#gmail.com',
userName: 'hari',
__v: 0
}
On the other hand, if you want login to be a list, you have to access:
login[0].userName

Node POST req returns same values regardless of input

I'm making a POST request like this:
router.post('/register2', (req, res) => {
const newUser = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password
});
newUser.save()
.then(res.json(newUser));
})
But, in Postman, no matter what I enter for my name/email/password values, it just returns the first set of values I ever tried. The id and date update each time, but name, email, and password ignore the input and give me the same things every time.
Here's the "User" that newUser refers to:
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model('users', UserSchema);

Trouble with object selection in Mongoose schema

Currently building an app whereby the user can log in either locally or via google (will be expanded to other social sites). I'm using an enum array to hold the possible login methods. My user schema looks as follows:
const userSchema = new Schema({
method :{
type: String,
enum: ['local', 'google', 'twitter'],
required: true
},
local: {
email: String,
username: String,
password: String,
projects: [
{
projectName: String,
sessionLength: Number,
timestamp: Date
}
]
},
google: {
googleId: String,
email: String,
username: String,
projects: [
{
projectName: String,
sessionLength: Number,
timestamp: Date
}
]
}
});
const User = mongoose.model('user', userSchema);
module.exports = User;
The following code is used to create the new user and save to the database after authentication by Google.
let newUser = new User({
method: 'google',
google: {
googleId: profile.id,
email: profile.emails[0].value,
username: profile.name.givenName
}
});
My problem is that newUser contains, as well as the correct google object, a 'local' object with a projects array. Below is how the newUser looks. I dont want it to include the local object. It also only seems to only appear if the projects property is an array, works as expected when projects is set to be a string. What am I doing wrong?
{ method: 'google',
_id: 5a32aaa4c665b062df9c0d00,
google:
{ googleId: 'randomgoogleId',
email: 'name#gmail.com',
username: 'name',
projects: [] },
local: { projects: [] } }

Resources