trying to assign value to schema in schema in mongoose in nodejs - node.js

so my mongoose model looks like this
userName:{
type:String,
required:true
},
userEmail:{
type:String,
required:true
},
userGym: gySchema,
userPassword:{
type:String,
required:true
}
gySchema is another schema and through patch method of https I am trying to assign a value to a variable in gySchema in Nodejs, how can I do so??

Below is the code for your reference as I too have done a project using this. When your using patch you have to just use req.body as it is what you want to update. and the route will be req.patch. patch is for partial update. put is for entire update.
model
const Joi = require("joi");
const mongoose = require("mongoose");
const { Genre, validateGenre, genreSchema } = require("./genre");
Joi.objectId = require("joi-objectid")(Joi);
const movieSchema = new mongoose.Schema({
title: {
type: String,
required: true,
minlength: 5,
maxlength: 50,
},
numberInStock: {
type: Number,
required: true,
min: 0,
max: 255,
default: 13,
},
dailyRentalRate: {
type: Number,
min: 0,
max: 255,
required: true,
},
liked: {
type: Boolean,
default: false,
},
genre: {
type: genreSchema,
required: true,
},
});
const Movie = mongoose.model("Movie", movieSchema);
function validateMovie(movie) {
const schema = {
title: Joi.string().required().min(5).max(255),
numberInStock: Joi.number().required().min(0).max(255),
dailyRentalRate: Joi.number().required().min(0).max(255),
liked: Joi.boolean(),
genreId: Joi.objectId().required(),
_id: Joi.objectId(),
};
return Joi.validate(movie, schema);
}
module.exports.Movie = Movie;
module.exports.validateMovie = validateMovie;
routes
const express = require("express");
const { Movie, validateMovie } = require("../models/movie");
const { Genre } = require("../models/genre");
const auth = require("../middlewares/auth");
const admin = require("../middlewares/admin");
const validateObjectId = require("../middlewares/validateObjectId");
const router = express.Router();
router.get("/", async (req, res) => {
const movies = await Movie.find();
res.send(movies);
});
router.post("/", async (req, res) => {
//validate the movie
const { error } = validateMovie(req.body);
if (error) {
console.log(error);
return res.status(400).send(error.details[0].message);
}
const genre = await Genre.findById(req.body.genreId);
if (!genre) {
return res.status(400).send("No genre found with given id");
}
const movie = new Movie({
title: req.body.title,
numberInStock: req.body.numberInStock,
dailyRentalRate: req.body.dailyRentalRate,
liked: req.body.liked,
genre: {
_id: genre._id,
name: genre.name,
},
});
// console.log(movies);
await movie.save();
console.log("Saving the document...");
res.send(movie);
});
//updating
router.put("/:id", async (req, res) => {
const { error } = validateMovie(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
}
let genre = await Genre.findById(req.body.genreId);
console.log(genre);
if (!genre) {
return res.status(400).send("No genre found with given id");
}
let movieDetails = await Movie.findByIdAndUpdate(
req.params.id,
{
title: req.body.title,
numberInStock: req.body.numberInStock,
dailyRentalRate: req.body.dailyRentalRate,
liked: req.body.liked,
genre: {
_id: genre.id,
name: genre.name,
},
}, //when using patch method, then u need not have to write this whole thing. instead just write req.body
{ new: true }
);
if (!movieDetails) {
return res.status(404).send("No such movie details found.");
}
res.send(movieDetails);
});
router.delete("/:id", async (req, res) => {
let movieDetails = await Movie.findByIdAndDelete(req.params.id);
if (!movieDetails) {
return res.status(404).send("No id found for given Movie");
}
res.send(movieDetails);
});
module.exports = router;

Related

Category and subcategory API node design

I am creating an ecommerce project, so there will be like a category ('men'), and subcategory of it "men's shoes", and an admin user can use addcategory in the mongodb, I found some code snippet from youtube, but the logic is so confusing, and I have no idea. can anyone kindly explain the step to step how to create this type of API?
in my category model file, I have this:
const mongoose = require("mongoose");
const categorySchema = new mongoose.Schema(
{
name: { type: String, required: true, unique: true, trim: true },
slug: { type: String, required: true, unique: true },
parentID: {
type: String,
},
},
{ timestamps: true }
);
module.exports = mongoose.model("Category", categorySchema);
in the category controller file:
const Category = require("../models/category");
const slugify = require("slugify");
function createCategories(categories, parentId = null) {
const categoryList = [];
let category;
if (parentId == null) {
categories.filter((cat) => cat.parentId == undefined);
} else {
category = categories.filter((cat) => cat.parentId === parentId);
}
for (let cate of category) {
categoryList.push({
_id: cate._id,
name: cate._name,
slug: cate.slug,
children: createCategories(categories.cate._id),
});
}
return categoryList;
}
exports.addCategory = (req, res) => {
const categoryObj = {
name: req.body.name,
slug: slugify(req.body.name),
};
if (req.body.parentId) {
categoryObj.parentId = req.body.parentId;
}
const cat = new Category(categoryObj);
cat.save((error, category) => {
if (error) return res.status(400).json({ error });
if (category) {
return res.status(201).json({ category });
}
});
};
exports.getCategories = (req, res) => {
Category.find({}).exec((error, categories) => {
if (error) console.log(error);
if (categories) {
const categoryList = createCategories(categories);
res.status(200).json({ categoryList });
}
if (categories) {
res.status(200).json({ categories });
}
});
};

How to waiting while document updating in mongoose?

I have this code:
module.exports = async (msg) => {
const postId = msg.wall.copyHistory[0].id;
const userId = msg.wall.ownerId;
const bonusePostManager = new BonusePostManager(postId)
const post = await bonusePostManager.getPost(postId);
if (!post) return;
if (post.reposters.includes(userId)) return;
const balanceManager = new BalanceManager(userId, 0);
const doubleCheckReposter = await bonusePostManager.getPost(postId);
if (doubleCheckReposter?.reposters.includes(userId)) return;
bonusePostManager.addReposter(userId)
.catch(console.error)
.then((res) => {
balanceManager.plusBalance(post.bonuseAmount, 'balance').then(async (res) => {
await messageAssistant.sendMessage({
peer_id: userId,
text: `Вы сделали репост, вы получаете ${numberWithSpace(post.bonuseAmount)}`
})
})
})}
If a person makes a repost from two devices at the same time, then the document does not have time to update and allows the possibility of a double repost. I tried using the $addToSet operator:
addReposter(userId, postId = this.postId) {
return Bonuse.updateOne({
id: postId,
}, {
$addToSet: {
'reposters': userId
}
})
}
But it doesn't help, I really don't know how to fix it. I return the promiss everywhere, try to wait for them, but this does not fix the situation, please help me!
I also attach the BonusePost scheme:
const { Schema } = require('mongoose');
const PostSchema = new Schema({
postId: {
type: Number,
unique: true,
index: true
},
active: {
type: Boolean,
default: true,
index: true,
},
bonuseAmount: {
type: Number,
},
reposters: {
type: Array,
default: [],
}
})
module.exports = PostSchema;
And model:
const { model } = require('mongoose');
const PostSchema = require('./schema');
const Bonuse = new model('Bonuse', PostSchema)
module.exports = Bonuse;

ObjectParameterError: Parameter "filter" to find() must be an object, got search

this get route is giving no error in post-man but doing the same with frontend giving error in node console:
ObjectParameterError: Parameter "filter" to find() must be an object, got search
although response are fetched.
get controller
const Recent = require("../models/recent");
const getRecentByName = async (req, res, next) => {
const name = req.params.name;
let regex = new RegExp(name, "i");
let players;
try {
players = await Recent.find({ name: { $regex: regex } });
} catch (err) {
return next(err);
}
if (!players) {
return next("no player found");
}
// console.log(players);
res.json({ players });
};
exports.getRecentByName = getRecentByName;
fetching from frontend:
const searchRecords = async () => {
const data = await sendRequest(
"http://localhost:5000/api/player/recent/search/" + search,
"GET"
);
setRecord(data.players);
};
Recent:(mongoose Schema):
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const recentSchema = new Schema({
name: { type: String, required: true },
recent: [
{
team1: { type: String },
team2: { type: String },
points: { type: Number, required: true },
date: { type: Date },
},
],
});
module.exports = mongoose.model("Recent", recentSchema);
I think the problem is from the front and in the URL
you should use
http://localhost:5000/api/player/recent/search/${search}

Tools to create a functional Shopping Cart

I'm creating an e-commerce using Reactjs for frontend and Nodejs for backend (also express), and i want to create an shopping cart "connected" to the user account, where the user can recharge the page, close it, and the cart doesn't reset.
I'm looking for tools to create this, or some tutorial to do it with node-express, thanks! (i don't have code yet, cause i don't know from where starts)
This is User Model with Cart( with add-to-cart and remove from cart Function )
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema({
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
resetToken: String,
resetTokenExpiration: Date,
cart: {
items: [
{
productId: {
type: Schema.Types.ObjectId,
ref: "Product",
required: true,
},
quantity: {
type: Number,
required: true,
},
},
],
},
});
userSchema.methods.addToCart = function (product) {
const cartProductIndex = this.cart.items.findIndex((cp) => {
return cp.productId.toString() === product._id.toString();
});
let newQuantity = 1;
const updatedCartItems = [...this.cart.items];
if (cartProductIndex >= 0) {
newQuantity = this.cart.items[cartProductIndex].quantity + 1;
updatedCartItems[cartProductIndex].quantity = newQuantity;
} else {
updatedCartItems.push({
productId: product._id,
quantity: newQuantity,
});
}
const updatedCart = {
items: updatedCartItems,
};
this.cart = updatedCart;
return this.save();
};
userSchema.methods.removeFromCart = function (productId) {
const UpdatedCartItems = this.cart.items.filter((item) => {
return item.productId.toString() !== productId.toString();
});
this.cart.items = UpdatedCartItems;
return this.save();
};
userSchema.methods.clearCart = function () {
this.cart = { items: [] };
return this.save();
};
module.exports = mongoose.model("User", userSchema);
Here, Routes
router.get("/cart", (req, res, next) => {
req.user
.populate("cart.items.productId")
.then((user) => {
const products = user.cart.items;
// console.log(products);
res.render("home/cart", {
path: "/cart",
pageTitle: "Your cart",
products: products,
isAuthenticated: req.session.isLoggedIn,
});
// console.log(products);
})
.catch((err) => {
console.error(err);
});
});
router.post("/cart",(req, res, next) => {
const prodId = req.body.productId;
// console.log(prodId);
Product.findById(prodId)
.then((product) => {
return req.user.addToCart(product);
})
.then((result) => {
// console.log(result);
res.redirect("/cart");
});
});
Tech:-
Frontend:- Ejs View Engine
Backend:- Express, MongoDB Atlas

Updating a field in MondoDB

I am writing a multi-user online dictionary. I want to implement a leadership board, e.i. "score" attribute increases, as soon as a user adds a word. I have a rough idea on how to do it, and tried one solution, however it does not work. Could you please guide me?
Word API route
const express = require('express');
const router = express.Router();
const Word = require('../../models/Word');
const User = require('../../models/User');
const validateWordInput = require('../../validation/word');
const passport = require('passport');
// #route POST api/words
// #desc Add words to profile
// #access Private
router.post(
'/',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const { errors, isValid } = validateWordInput(req.body);
// Check validation
if (!isValid) {
// Return any errors
return res.status(400).json(errors);
}
Word.find({}).then(word => {
if (
word.filter(
wrd =>
wrd.ugrWordCyr.toString().toLowerCase() ===
req.body.ugrWordCyr.toLowerCase()
).length !== 0
) {
return res
.status(404)
.json({ wordalreadyexists: 'Word already exists' });
} else {
const newWord = new Word({
user: req.user.id,
ugrWordCyr: req.body.ugrWordCyr,
rusTranslation: req.body.rusTranslation,
example: req.body.example,
exampleTranslation: req.body.exampleTranslation,
origin: req.body.origin,
sphere: req.body.sphere,
lexis: req.body.lexis,
grammar: req.body.grammar,
partOfSpeech: req.body.partOfSpeech,
style: req.body.style
});
newWord.save().then(word => res.json(word));
User.update(
{ _id: '5cf0cb78b3105d1ba8e30331' },
{ $inc: { score: 1 } }
);
}
});
}
);
User model
This is where a score attribute is located
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create schema
const userSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
score: {
type: Number,
default: 0
},
avatar: {
type: String
},
date: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model('users', userSchema);
After successfully saving the word, we should update the user count
To update the respective user's score you can do the following:
newWord.save().then((word) => {
//now update user model
User.findOne({ _id: req.user.id }) <-- or an id you would like
.then((foundUser) => {
foundUser.score = foundUser.score + 1
foundUser.save()
.then((savedUser) => {
res.json({ word, savedUser })
})
.catch((err) => {
return res.status(400).json({ error: "could not add score"})
})
})
.catch((err) => {
return res.status(400).json({ error: "could not find user"})
})
})

Resources