Reputation: 155
I have three schemas.
User.js:
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
unique: true,
required: true,
},
password: {
type: String,
required: true,
},
});
userSchema.pre("save", function (next) {
const user = this;
if (!user.isModified("password")) {
return next();
}
bcrypt.genSalt(10, (err, salt) => {
if (err) {
return next(err);
}
bcrypt.hash(user.password, salt, (err, hash) => {
if (err) {
return next(err);
}
user.password = hash;
next();
});
});
});
userSchema.methods.comparePassword = function (candidatePassword) {
const user = this;
return new Promise((resolve, reject) => {
bcrypt.compare(candidatePassword, user.password, (err, isMatch) => {
if (err) {
return reject(err);
}
if (!isMatch) {
return reject(false);
}
resolve(true);
});
});
};
mongoose.model("User", userSchema);
Project.js:
const mongoose = require("mongoose");
const diamondSchema = new mongoose.Schema({
criteria: {
novelty: String,
technology: String,
complexity: String,
pace: String,
},
});
const projectSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
projectName: {
type: String,
default: "",
},
projectBudget: {
type: Number,
},
projectDuration: {
type: Number,
},
industry: {
type: String,
},
companyName: {
type: String,
},
numberOfEmployees: {
type: Number,
},
diamond: [diamondSchema],
});
mongoose.model("Project", projectSchema);
Recommendation.js:
const mongoose = require("mongoose");
const diamondSchema = new mongoose.Schema({
criteria: {
novelty: String,
technology: String,
complexity: String,
pace: String,
},
});
const recommendationSchema = new mongoose.Schema({
diamond: [diamondSchema],
description: {
type: String,
},
});
mongoose.model("Recommendation", recommendationSchema);
And two route files.
authRoutes.js:
const express = require("express");
const mongoose = require("mongoose");
const User = mongoose.model("User");
const jwt = require("jsonwebtoken");
const router = express.Router();
router.post("/signup", async (req, res) => {
const { name, email, password } = req.body;
try {
const user = new User({ name, email, password });
await user.save();
const token =
//token has payload-->user id
jwt.sign({ userId: user._id }, "MY_SECRET_KEY");
res.send({ token });
} catch (err) {
//invalid data
return res.status(422).send(err.message);
}
});
router.post("/signin", async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(422).send({ error: "Must provide email and password" });
}
const user = await User.findOne({ email });
if (!user) {
return res.status(404).send({ error: "Invalid email or password" });
}
try {
await user.comparePassword(password);
const token = jwt.sign({ userId: user._id }, "MY_SECRET_KEY");
res.send({ token });
} catch (err) {
return res.status(422).send({ error: "Invalid email or password" });
}
});
module.exports = router;
projectRoutes.js:
const express = require("express");
const mongoose = require("mongoose");
const requireAuth = require("../middlewares/requireAuth");
const Project = mongoose.model("Project");
const Recommendation = mongoose.model("Recommendation");
const router = express.Router();
router.use(requireAuth);
router.get("/projects", async (req, res) => {
const projects = await Project.find({ userId: req.user._id });
res.send(projects);
});
router.post("/projects", async (req, res) => {
const {
projectName,
projectBudget,
projectDuration,
industry,
companyName,
numberOfEmployees,
diamond,
} = req.body;
if (
!projectName ||
!projectBudget ||
!projectDuration ||
!industry ||
!companyName ||
!numberOfEmployees ||
!diamond
) {
return res.status(422).send({ error: "Must provide all project details" });
}
try {
const project = new Project({
projectName,
projectBudget,
projectDuration,
industry,
companyName,
numberOfEmployees,
diamond,
userId: req.user._id,
});
await project.save();
//res.send(project);
} catch (err) {
res.status(422).send({ error: err.message });
}
try {
const rec = await Recommendation.find({ diamond });
//console.log(diamond);
console.log(description);
res.send(rec);
} catch (err1) {
res.status(422).send({ error: err1.message });
}
});
module.exports = router;
Using postman, in the projectRoutes.js file, when I try to send the post request on
localhost:3000/projects
, I am trying to create a new project and in response I want description
. My logic is that, after I save the new project in projects
collection, I am trying to find the document with the SAME DIAMOND OBJECT criteria
in recommendations
collection which is also present in projects
collection. Meaning, I have pre-defined records in recommendations
collection and projects
collection::
So I need some way so that when I try to add a new project for a user, the criteria
object in diamond
array I set matches to the criteria object in diamond
array in pre-defined one of recommendations
documents and in the post request localhost:3000/projects
I can return description
in response. As I'm doing console.log(description)
in projectRoutes.js
, it's showing as undefined. I don't know why. Hope it makes sense.
Basically, the idea is there will be limited number of recommendations with unique criterias. So whenever a new project is created based on the criteria, a recommendation is displayed to the user.
Upvotes: 0
Views: 38
Reputation: 5245
Assuming you have only one array element in a project and in an a recommendation
const {
projectName,
projectBudget,
projectDuration,
industry,
companyName,
numberOfEmployees,
diamond,
} = req.body;
const [projectDiamond] = diamond // get the first object in the diamond array
const { criteria } = projectDiamond // extract criteria
const recommendation = await Recommendation.find({ 'diamond.criteria': criteria });
Please note that the order of criteria fields must match, since we are looking up a matching object in an array.
Reference: https://docs.mongodb.com/manual/tutorial/query-arrays/#query-an-array
Upvotes: 1