I have a user Full stack tool, and i've separated the users into 'users' and 'companyusers' respectively within my backend.
Within this, I have a fully fuctioning GET for users, which looks like this:
router.get("/findUser/:id", async (req,res)=>{
try{
const user = await User.findById(req.params.id)
const { password, ...others } = user._doc;
res.status(200).json(others);
}catch(err){
res.status(500).json(err)
}
})
Pretty generic, but it works.
I've created the schema:
const mongoose = require("mongoose")
//CompanyProfileSchema
const CompanyProfileSchema = new mongoose.Schema(
{
companyTitle:{type:String, required: true, unique: true, default: ""},
companyPassword:{type:String, required: true, default: ""},
centralEmail:{type:String, required: true, unique: true, default: ""},
description:{type:String, required: true, default: ""},
industry:{type:String, required: true},
employees:{type: Number},
companyImage: {type:String, required: false, unique: false, default: ""},
locationCity:{type:String, required: false, unique: false, default: ""},
industry:{type:String, required: false, unique: false, default: ""},
country:{type:String, required: false, unique: false, default: ""},
highlights: {type: Array},
isAdmin:{
type: Boolean,
default: false,
},
isVerified:{
type: Boolean,
default: false,
},
invitedUsers: {type: Array}
},
);
module.exports = mongoose.model("CompanyUser", CompanyProfileSchema)
Which works and is in the index.js as such
app.use("/api/users", userRoute)
app.use("/api/companyprofile", companyprofileRoute)
However, in my companyprofile request file, when I complete the request, I am getting empty data back:
const CompanyProfile = require("../models/CompanyProfile");
const { route } = require("./auth");
router.get("/findCompany/:id", async (req,res)=>{
try{
const companyUser = await CompanyProfile.findById(req.params.id)
res.status(200).json(req.params.body);
const { password, ...others } = companyUser._doc;
// res.status(200).json({others});
}catch(err){
res.status(500).json(err)
}
})
This is with a request like:
localhost:5000/api/companyprofile/findCompany/61f2980a7d4bb550edf8ec7e
and a body of
{
"centralEmail": "natia1#bank.com.au"
}
Any ideas?
Related
I'm building an authentication link which is sent by the company to their team member to allow them access to join.
Currently, my logic is looking something like this - with a bit of semi-code.
Firstly, I have two schema's, one for company and one for user.
const CompanyProfileSchema = new mongoose.Schema(
{
companyTitle:{type:String, required: true, unique: true, default: ""},
companyPassword:{type:String, required: true, default: ""},
centralEmail:{type:String, required: true, unique: true, default: ""},
description:{type:String, required: true, default: ""},
inviteToken:{type:String, required: true, default:""},
industry:{type:String, required: true},
employees:{type: Number},
companyImage: {type:String, required: false, unique: false, default: ""},
locationCity:{type:String, required: false, unique: false, default: ""},
industry:{type:String, required: false, unique: false, default: ""},
country:{type:String, required: false, unique: false, default: ""},
teamMembers: {
type: String, required: true, default: 0
},
teamMemberDetails: {
memberName: [String], default: [],
memberEmail: [String], default: [],
memberRole: [String], default: []
},
highlights: {type: Array},
isAdmin:{
type: Boolean,
default: false,
},
isVerified:{
type: Boolean,
default: false,
},
accountLevel: {type: Array},
emailAuthorised: { type: Boolean, default: false},
invitedUsers: {type: Array}
},
);
module.exports = mongoose.model("CompanyUser", CompanyProfileSchema)
const UserSchema = new mongoose.Schema(
{
//userdetails
username: {type: String, required: true, default: "" },
password:{type:String, required: true},
//profile
fullname:{type:String, required: false, default: "none"},
firstname:{type:String, required: false, default: "", unique: false},
surname:{type:String, required: false, default: "", unique: false},
email:{type:String, required: true, unique: true},
position: {type:String, required: false, unique: false},
recruiter: {type: Boolean}, //Canidate or Recruiter,
userImage: {type:String, required: false, unique: false, default: ""},
//location
locationCity:{type:String, required: false, unique: false, default: ""},
country:{type:String, required: false, unique: false, default: ""},
//work
role:{type:String, required: false, default: ""},
company: {type:String, default: ""},
emailAuthorised: { type: Boolean, default: false},
professionalBio: {type:String, default: ""},
positionRecentTitle : {type:String, default: ""},
positionRecentCompany : {type:String, default: ""},
companyAuthorised: {type: String, default: ""},
isAdmin:{
type: Boolean,
default: false,
},
},
{timestamps: true }
);
module.exports = mongoose.model("User", UserSchema)
I have create an API endpoint which sends out an email with the auth token of the company.
I would like to firstly find the user in the DB and update the field 'companyAuthorised' with the userToken of the company.
Secondly, I'd also like to find the company with the token also and update their teamMemberDetails.Email to be the email in the endpoint.
I have created some psuedo code which I think is pretty close, can anyone clarify?
router.get('/inviteToJoinTeam/:token/:email', async (req, res) => {
try {
//verify the token against DB
const userToken = (req.params.token)
const indivEmailAdd = (req.params.email)
// creating user auth
try{
const userDetails = await User.find({email: indivEmailAdd})
const { password, ...others } = userDetails._doc;
const userID = userDetails.id
const updateUser = await User.findByIdAndUpdate(userID, { companyAuthorised: {userToken}});
}catch{
console.log('failure')
}
// creating company auth
try{
const companyDetails = await CompanyUser.find({inviteToken: userToken})
const { password, ...others } = companyDetails._doc;
const companyID = companyDetails.id
const updateCompany = await CompanyUser.findByIdAndUpdate(companyID, { teamMemberDetails.memberEmail: {indivEmailAdd}});
}catch{
console.log('failure')
}
console.log('successfully completed try')
res.send('final')
} catch (e) {
res.send('This isnt working');
}
});
Regards
If I correctly understand your use case, the code you are looking to write would be the following:
router.get('/inviteToJoinTeam/:token/:email', async (req, res) => {
try {
//verify the token against DB
const userToken = req.params.token;
const indivEmailAdd = req.params.email;
// creating user auth
try {
const updatedUser = await User.findOneAndUpdate(
{ email: indivEmailAdd },
{ companyAuthorised: userToken },
).lean();
} catch {
console.log('failure');
}
// creating company auth
try {
const updatedCompany = await CompanyUser.findOneAndUpdate(
{ inviteToken: userToken },
{
'teamMemberDetails.memberEmail': indivEmailAdd,
},
).lean();
} catch {
console.log('failure');
}
console.log('successfully completed try');
res.send('final');
} catch (e) {
res.send('This isnt working');
}
});
I am new in backend development.
I am trying to create profile endpoints to get all profiles with the gender of the user is either male or female.
Profile contains user as a objectID.
I want to filter profiles using users gender.
My UserSchema looks like this
const userSchema = mongoose.Schema(
{
firstname: {
type: String,
required: true,
trim: true,
},
lastname: {
type: String,
required: true,
trim: true,
},
email: {
type: String,
required: true,
unique: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Invalid email');
}
},
},
password: {
type: String,
required: true,
trim: true,
minlength: 8,
validate(value) {
if (!value.match(/\d/) || !value.match(/[a-zA-Z]/)) {
throw new Error('Password must contain at least one letter and one number');
}
},
private: true, // used by the toJSON plugin
},
role: {
type: String,
enum: roles,
default: 'user',
},
gender: {
type: String,
enum: genders,
required: true,
},
profileStatus: {
type: String,
enum: profileStatus,
default: 'inProgress',
},
isEmailVerified: {
type: Boolean,
default: false,
},
},
{
timestamps: true,
}
);
And Profile schema looks like this
const profileSchema = new Schema(
{
user: { type: Schema.Types.ObjectId, ref: 'User', required: true, unique: true },
bio: { type: String, required: true },
profilePicUrl: {
type: String,
required: true,
},
birthdate: {
type: Date,
required: true,
},
profession: {
type: String,
required: true,
},
profileCompletion: {
type: Number,
default: 50,
min: 0,
max: 100,
},
credits: {
type: Number,
default: 2,
min: 0,
},
lastLogin: {
type: Date,
default: new Date(),
required: true,
},
},
{ timestamps: true }
);
I want to find profiles where user gender is male or female.
How can I do that?
You can create a endpoint like this and use .find() to find all the users with the gender passed by user
router.get(/user/:gender, async (req, res) => {
try {
const users = await User.find({ gender: req.params.gender }).exec();
res.status(200).json(users);
} catch (err) {
return res.status(500);
}
})
I want to store or push whole reference document not a single reference id in Mongoose using Node.js.
Here user api details schema:
const {Schema} = require("mongoose");
const mongoose = require("mongoose");
const apiDetailSchema = new Schema({
endpoint:
{
type: String,
required: true,
trim: true
},
method:
{
type: String,
required: true,
trim: true,
},
secret:
{
type: String,
required: true,
trim: true
},
timeout:
{
type: Number,
required: true,
},
microservice:
{
type: String,
required: true,
},
status:
{
type: Number,
required: true,
},
user_type_id:
{
type: Schema.Types.ObjectId,
ref: 'UserType',
required: true
}
});
module.exports = apiDetailSchema;
Permissoin Schema
const {Schema} = require("mongoose");
const mongoose = require("mongoose");
const permission = new Schema({
role:
{
type: Schema.Types.ObjectId,
ref: 'Role'
},
Here I want to store whole api details document not single id
api_details:
[
{
type: Schema.Types.ObjectId,
ref: 'ApiDetail'
}
],
group:
{
type: String,
default: 0,
trim: true
},
status:
{
type: Number,
default: 0,
trim: true
}
});
module.exports = permission;
And here I push the ids like this:
async createPermission(req, res)
{
const permission = new Permission({
"role": req.body.role,
"group": req.body.group,
"status": req.body.status
});
const newPermissoin = await permission.save();
if(newPermissoin) {
const updatePermission = await Permission.findByIdAndUpdate(
newPermissoin._id,
{ $push: { "api_details": req.body.api_details_id } },
{ new: true, useFindAndModify: false }
);
return res.json( Response.success({message:
"Permission created successfully!", data: updatePermission}) );
}
}
How do I store the whole documents of api details in array form but here only reference of ids are stored.
little bit stuck with one issue which is related to mongoose. I have a Project schema with sub-schema(SingleUserSchema). Whenever I add a new User to this schema it saves everything and that's ok. The issue is that if I update the user, old values in schema does not update. Any ideas how to solve this case? Stuck here for a whole day already.
Schema:
const mongoose = require('mongoose');
const SingleUserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
},
role: {
type: String,
required: true,
},
status: {
type: String,
required: true,
},
});
const ProjectSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, 'Provide project name'],
minlength: 5,
},
description: {
type: String,
required: [true, 'Provide description about the project'],
},
maxWorkingEmployees: {
type: Number,
required: [
true,
'Provide maximum number of employees working on this project',
],
},
currentlyWorkingEmployees: [SingleUserSchema],
status: {
type: String,
enum: ['Pending', 'In progress', 'Paused', 'Delayed', 'Completed'],
default: 'Pending',
},
createdBy: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('Project', ProjectSchema);
Controller:
const attachEmployeeToProject = async (req, res) => {
const { projectId, userId } = req.params;
const project = await Project.findOne({ _id: projectId });
const user = await User.findOne({ _id: userId });
if (!user) {
throw new NotFoundError(`User with id ${userId} does not exists`);
}
if (!project) {
throw new NotFoundError(`Project with id ${userId} does not exists`);
}
const { role, email, status } = user;
const SingleUserSchema = {
email,
role,
status,
};
let currentlyWorkingEmployees = [
...project.currentlyWorkingEmployees,
SingleUserSchema,
];
req.body.currentlyWorkingEmployees = currentlyWorkingEmployees;
const updateProject = await Project.findOneAndUpdate(
{ _id: projectId },
req.body,
{
new: true,
runValidators: true,
}
);
res.status(StatusCodes.OK).json({ updateProject });
};
Maybe I just simply need to create a reference? Tried like this and received tons of errors, also felt lost how to create n references in array.
currentlyWorkingEmployees: [
{ type: mongoose.Schema.ObjectId, ref: 'User', required: true },
],
User schema:
const UserSchema = new mongoose.Schema({
username: {
type: String,
required: [true, 'Please provide username'],
minlength: 3,
maxlength: 50,
},
email: {
type: String,
required: [true, 'Please provide username'],
unique: true,
validate: {
validator: validator.isEmail,
message: 'Please provide valid email address',
},
},
password: {
type: String,
required: [true, 'Please provide password'],
validator: {
validate: {
validator: validator.isStrongPassword,
message: 'Please provide stronger password',
},
},
},
firstname: {
type: String,
required: [true, 'Please provide first name'],
},
lastname: {
type: String,
required: [true, 'Please provide last name'],
},
status: {
type: String,
enum: ['Working', 'Pause', 'Offline'],
default: 'Offline',
},
role: {
type: String,
enum: [
'Developer',
'Analyst',
'Designer',
'Architect',
'Project Manager',
'Owner',
'Teamleader',
'Employee',
],
default: 'Employee',
},
verificationToken: {
type: String,
},
isTokenVerified: {
type: Boolean,
default: false,
},
tokenValidationDate: {
type: Date,
default: null,
},
});
First, as far as I see you don't have a model called 'User' so that's the reason why your reference is not working.
currentlyWorkingEmployees: [
{ type: mongoose.Schema.ObjectId, ref: 'User', required: true },
]
https://mongoosejs.com/docs/populate.html
Second, you need to identify the user you want to update (based on userId) inside currentlyWorkingEmployees collection, if I understood correctly your problem.
Hope it helps!
I have 2 models, a user model, and a follow model that handles the following of users. I would like to be able to get the followers to users in a get request. How can I get this?
Below is the user model
const userSchema = new mongoose.Schema({
fullname: {
type: String,
required: true,
trim: true,
lowercase: true
},
username: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true
},
email: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
password: {
type: String,
required: true,
minlength: 7,
trim: true,
validate(value) {
if (value.toLowerCase().includes('password')) {
throw new Error('Passwoed cannot contain "password"')
}
}
},
isActive: {
type: Boolean,
required: false,
default: true
}
})
Here is the Follow model that handles the following of users. When a logged-in user follows another user, we set the followedBy to the logged-in user and the user to the user that is getting followed.
const followSchema = new mongoose.Schema({
// the logged in user who will be trying to follow someone will be added to "followedBy"
// the user who is getting followed will be added to "user"
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User'
},
followedBy: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Showcase'
}
}, {
timestamps: true
})
Below is the post request where I would like to get a list of object id's that follows a user (passed through the id in the parameter)
// Get a users followers
router.get('/api/:id/followers', async (req, res) => {
try {
const followers = await Follow.find({
user: req.params.id
})
console.log(followers.followedBy)
res.status(200).send(followers)
} catch (e) {
res.status(500).send()
}
})
How can I get the object id's of followedBy?
You could put the followers and following actions into the user schema as attributes
const userSchema = new mongoose.Schema({
fullname: {
type: String,
required: true,
trim: true,
lowercase: true
},
username: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true
},
email: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
password: {
type: String,
required: true,
minlength: 7,
trim: true,
validate(value) {
if (value.toLowerCase().includes('password')) {
throw new Error('Passwoed cannot contain "password"')
}
}
},
isActive: {
type: Boolean,
required: false,
default: true
},
following: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
],
followers: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
]
});
const User = mongoose.model('User', userSchema)
if you still want to stick to having a Follow model here's a solution you might like
const followSchema = new mongoose.Schema({
//user below is the user that is being followed
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User'
},{
timestamps: true
});
const Follow = mongoose.model('Follow', followSchema);
const userSchema = new mongoose.Schema({
fullname: {
type: String,
required: true,
trim: true,
lowercase: true
},
username: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true
},
email: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
password: {
type: String,
required: true,
minlength: 7,
trim: true,
validate(value) {
if (value.toLowerCase().includes('password')) {
throw new Error('Passwoed cannot contain "password"')
}
}
},
isActive: {
type: Boolean,
required: false,
default: true
},
following: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Follow",
},
],
followers: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Follow",
},
]
});
const User = mongoose.model('User', userSchema);
we can have a follow route in our API or server:
app.post('/follow/:user_id', (req, res) => {
//perform follow code
})
When user A clicks on a button to follow user B, we pass in user B's user_id as a parameter to our API like this
http://localhost:54757/follow/userB_id
We already know we're in user A's account because he's the one clicking on the follow button, so we can just get user A's user Id using an auth token that we must have given him upon signup/signin
In our API we create 2 new objects from the Follow model using the follow route
app.post('/follow/:user_id', (req, res) => {
//push this one into user B's "followers" array and save user B
const new_follow1 = new Follow({
user: userA_id //id gotten from session or auth token
});
//push this one into user A's "following" array and save user A
const new_follow2 = new Follow({
user: req.params.userB_id //id gotten from request parameters req.params
});
})
then finally save the two new Follows
new_follow1.save();
new_follow2.save()