How to make a record in mongodb refrence model - node.js

I working on Mongoose and Express project where by I have 3 models: User, Album and Purchase. The purchase model references the user and album. I am creating a POST endpoint where by I can make a purchase and then retrieve the data as well as the user and album relations which should be populated with their data, but I am stuck.
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
// TODO: Define Schema
name: {
type: String,
required: true
}
})
var User = mongoose.model('User', userSchema)
var albumSchema = mongoose.Schema({
// TODO: Define Schema
title: {
type: String,
required: true
},
performer: {
type: String,
required: true
},
cost: {
type: Number,
required: true
}
})
var Album = mongoose.model('Album', albumSchema);
var puchaseSchema = mongoose.Schema({
// TODO: Define Schema
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Album'
},
album: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
})
var Purchase = mongoose.model('Purchase', puchaseSchema);
app.use(bodyParser.json());
app.listen(3000);
// TODO: GET /albums
app.get('/albums', (req,res) => {
Album.find()
.then((response) => {
res.json({data: response})
})
.catch(err => {
res.json({error: err})
})
})
// TODO: GET /albums/:id
app.get('/albums/:id', (req,res) => {
Album.findById(req.params.id)
.then(response => {
res.json({data: response})
.catch(err => {
res.json({Error: err})
})
})
})
// TODO: POST /albums
app.post('/albums', (req,res) => {
const newPost = Album({
title: req.body.title,
performer: req.body.performer,
cost: req.body.cost
})
newPost.save(err => {
if(err)
res.json({error: err})
})
.then(data => {
res.json({data: data})
})
})
// TODO: PUT /albums/:id
app.put('/albums/:id', (req,res) => {
Album.findByIdAndUpdate(req.params.id, req.body, {new: true},
(err, album) =>{
if(err) return res.status(500).send(err)
return res.json({data: album})
})
})
// TODO: DELETE /albums/:id
app.delete('/albums/:id', (req,res) => {
const id = req.params.id
Album.findById(id)
.then(docs => {
docs.remove()
res.status(204)
.json({data:docs})
})
})
// TODO: POST /purchases
app.post('/purchases', (req,res) => {
})```

This might help you. Look into mongoose's populate method.
app.post('/purchases', (req,res) => {
const user = req.body.userId;
const album = req.body.albumId;
const newPurchase = new Purchase({
user: user,
album: album
});
newPurchase.save().then((purchase) => {
Purchase.findById(purchase.id).populate('user').populate('album').then((purchaseData) => {
return res.json({purchaseData});
}).catch(e => {
console.log(e);
});
}).catch(e => {
console.log(e);
});
})
Here's an alternative for populating after saving the document.
app.post('/purchases', (req,res) => {
const user = req.body.userId;
const album = req.body.albumId;
const newPurchase = new Purchase({
user: user,
album: album
});
newPurchase.save().then((purchase) => {
Purchase.populate(purchase, [{path: 'user'}, {path: 'album'}], (err, data) => {
if(err) {
return res.json(e);
}
return res.json(data);
});
}).catch(e => {
console.log(e);
});
}
)
As mentioned here: https://mongoosejs.com/docs/api.html#model_Model.populate

Related

Cannot push in mongodb

Im trying to create an API where users can create their fav movies and rate them.
So instead of creating a Movies array in user model, I created a Movie model with userId as an array. Now the logic is if there is a movie by the same name the new user is trying to create, it will not create a movie, rather it will push the userid and their rating. If there is no movie by that name it will create one. But I am stuck in that part. Any help will be hugely appreciated. Below im posting my code.
Movie model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const movieSchema = new Schema({
title: {
type: String,
required: true,
},
rating: [
{ type: Number, required: true, max: 5 },
],
userId: [
{
type: String,
},
],
});
const Movie = mongoose.model(
'Movie',
movieSchema
);
module.exports = Movie;
user model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: {
type: String,
required: true,
},
age: {
type: Number,
required: true,
},
// list: {
// type: Array,
// default: [],
// },
});
const User = mongoose.model('User', userSchema);
module.exports = User;
movie route
const router = require('express').Router();
const User = require('../models/User');
const Movie = require('../models/Movies');
//creating a movie
router.post(
'/:id/createmovie',
async (req, res) => {
const { title, rating } = req.body;
const userId = req.params.id;
try {
const currentMovie = await Movie.findOne({
title,
});
if (currentMovie == null) {
const newMovie = new Movie({
title,
rating,
userId,
});
newMovie
.save()
.then((data) => res.json({ data }))
.catch((err) => {
res.status(400).json({ error: err });
});
}
currentMovie
.updateOne(
{ title },
{ $push: { userId, rating } }
)
.then((data) => res.json({ data }))
.catch((err) => {
res.status(400).json({ error: err });
});
} catch (err) {
console.log(err);
}
}
);
// router.post('/:id/createmovie', (req, res) => {
// const { title, rating } = req.body;
// const userId = req.params.id;
// Movie.findOne({ title }).then((data) => {
// console.log(data);
// res.json(data);
// if (data == null) {
// res.send('true');
// }
// res.send('false');
// if (data.title == title) {
// Movie.updateOne(
// { title },
// { $push: { userId, rating } }
// );
// }
// const newMovie = new Movie({
// title,
// rating,
// userId,
// });
// newMovie
// .save()
// .then((data) => res.json({ data }))
// .catch((err) => {
// res.status(400).json({ error: err });
// });
// });
// });
router.get('/getmovie', (req, res) => {
const { title } = req.body;
Movie.find({ title })
.then((data) => res.json(data[0].title))
.catch((err) => {
res.status(400).json({ error: err });
});
});
module.exports = router;
Change router.post function arguments
router.post(
'/:id/createmovie',
async (req, res) => {
const { title, rating } = req.body;
const userId = req.params.id;
try {
const currentMovie = await Movie.findOne({
title,
});
if (currentMovie == null) {
await Movie.insertOne({title ,rating, userId})
.
}
else{
await Movie.updateOne(
{ title },
{ $push: { userId, rating } }
)
}
} catch (err) {
console.log(err);
}
}
);

.populate() returning empty array?

I'm working on project and I am trying to get the users reviews to display on the page. However whenever I run my application it returns an empty array and I'm not sure why, I have no issue with the getReviews function as it returns everything correctly, but getUserReviews just returns an empty array with no error. I've tried multiple methods and just can't seem to get it
Review Model
const mongoose = require("mongoose");
const Review = mongoose.model(
"Review",
new mongoose.Schema({
movieId: String,
reviewId: String,
content: String,
sentimentScore: String,
author: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}
],
reponseTo: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
]
})
);
module.exports = Review;
User Model
const mongoose = require("mongoose");
const User = mongoose.model(
"User",
new mongoose.Schema({
username: String,
email: String,
password: String,
roles: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Role"
}
]
})
);
module.exports = User;
Review Routes
const express = require('express');
const router = express.Router();
const {authJwt} = require("../middlewares");
const Review = require("../models/review.model")
router.use(function(req, res, next) {
res.header(
"Access-Control-Allow-Headers",
"x-access-token, Origin, Content-Type, Accept"
);
next();
});
router.post("/addReview", [authJwt.verifyToken], (req, res) => {
const review = new Review(req.body)
review.save((err, review) => {
if(err) return res.json({success:false, err})
Review.find({'_id': review._id})
.populate('author')
.exec((err, result) => {
if(err) return res.json({success: false, err})
return res.status(200).json({success: true, result})
})
})
})
router.post("/getReviews", [authJwt.verifyToken], (req, res) => {
Review.find({"movieId": req.body.data})
// console.log("ID ", req.body.data)
.populate('author')
.exec((err, reviews) => {
if(err) return res.status(400).send(err)
res.status(200).json({success: true, reviews})
})
})
router.post("/getUserReviews", [authJwt.verifyToken], (req, res) => {
Review.find({"userId": req.body.data})
.populate({
path: 'author.user',
model: 'Review'})
.exec((err, reviews) => {
if(err) return res.status(400).send(err)
res.status(200).json({success: true, reviews})
})
})
You try to query Review collection with userId field, and Review collection does not have userId field in its model definition.
Maybe you wanted to query author array? In that case, try this:
router.post("/getUserReviews", [authJwt.verifyToken], (req, res) => {
Review.find({ author: req.body.data })
.populate('author')
.exec((err, reviews) => {
if(err) return res.status(400).send(err)
res.status(200).json({success: true, reviews})
})
})

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

How to delete comment that is inside of Post schema?

I'm working on social network app where user can make post and comment. I'm trying to delete comment that is inside of a post. I work with MERN (mongoose, express, react, nodejs). I can successfully delete post, but don't know how to delete its comment.
This is my Mongo connection:
const db = config.get('mongoURI') mongoose.connect(db,{useNewUrlParser: true,useUnifiedTopology: true})
.then(() => console.log('Connected to MongoDB.'))
.catch(err => console.log('Fail to connect.', err))
this is Post Schema
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const PostSchema = new Schema({
userID: {
type: Schema.Types.ObjectId,
ref: 'user'
},
content: {
type: String,
required: true
},
registration_date: {
type: Date,
default: Date.now
},
likes: [
{
type: Schema.Types.ObjectId,
ref: "user"
}
],
comments: [
{
text: String,
userID: {
type: Schema.Types.ObjectId,
ref: 'user'
}
}
]
})
module.exports = User = mongoose.model('posts', PostSchema)
and here is where i tried to delete it:
router.delete("/comment/:postId/:commentId", auth, function (req, res) {
Post.findByIdAndUpdate(
(req.params.postId),
{ $pull: { comments: req.params.commentId } },
{ new: true }
)
.then(post => console.log(post)
.then(() => {
res.json({ success_delete: true })
})
.catch(() => res.json({ success_delete: false })))
});
Well, I think you are creating an app named DevConnector. So I wrote code for the same in the past.
router.delete('/comment/:id/:comment_id', auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
// Pull out comment
const comment = post.comments.find(
comment => comment.id === req.params.comment_id
);
// Make sure comment exists
if (!comment) {
return res.status(404).json({ msg: 'Comment does not exist' });
}
// Check user
if (comment.user.toString() !== req.user.id) {
return res.status(401).json({ msg: 'User not authorized' });
}
// Get remove index
const removeIndex = post.comments
.map(comment => comment.user.toString())
.indexOf(req.user.id);
post.comments.splice(removeIndex, 1);
await post.save();
res.json(post.comments);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});

How can I populate an existing Mongo Document when creating another?

I am using mongoose and express to build an API for storing technology work tickets. I have a field in my Ticket model that references a User id and an array field in my User model that references all the Tickets (by ID) that are owned by that user.
When I create a new Ticket (using HTTP post method), I want my database to automatically add that ticket's id to the tickets field of its assigned user (like a SQL Join). However, I can't get it to work.
I've tried updating my user model inside the /tickets POST request in my router, but can't wrap my head around how to actually make it work.
Here is my code:
// Ticket Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Promise = require('bluebird');
const ObjectId = mongoose.Schema.Types.ObjectId;
const User = require('./user');
Promise.promisifyAll(mongoose);
const TicketSchema = new Schema({
open: {type: Date, required: true},
close: Date,
description: {type: String, required: true},
done: Boolean,
status: String,
repairType: {type: String, required: true},
ticketOwner: {type: ObjectId, ref: 'User', required: true}
});
const Ticket = mongoose.model('Ticket', TicketSchema, 'tickets');
module.exports = Ticket;
// User Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Promise = require('bluebird');
const ObjectId = mongoose.Schema.Types.ObjectId;
const Ticket = require('./ticket');
Promise.promisifyAll(mongoose);
const UserSchema = new Schema({
firstName: {type: String, required: true},
lastName: {type: String, required: true},
email: {type: String, required: true},
tickets: [{type: ObjectId, ref: 'Ticket'}]
});
const User = mongoose.model('User', UserSchema, 'users');
module.exports = User;
// Tickets Route
const express = require('express');
const router = express.Router();
const Ticket = require('../models/ticket');
router.route('/')
// READ all tickets.
.get(function(req, res, next) {
Ticket.findAsync({})
.then(function(tickets) {
res.json(tickets);
})
.catch(next)
.error(console.error);
})
// CREATE new ticket.
.post(function(req, res, next) {
let ticket = new Ticket();
let prop;
for (prop in req.body) {
ticket[prop] = req.body[prop];
}
ticket.saveAsync()
.then(function(ticket) {
console.log('success');
res.json({'status': 'success', 'ticket': ticket});
})
.catch(function(e) {
console.log('fail');
res.json({'status': 'error', 'error': e});
})
.error(console.error);
});
router.route('/:id')
// READ a single Ticket by ID
.get(function(req, res, next) {
Ticket.findOne({_id: req.params.id}, {})
.populate('ticketOwner')
.exec(function (e, ticket) {
if (e) return console.error(e);
res.json(ticket);
})
})
// UPDATE a Ticket
.put(function(req, res, next) {
let ticket = {};
let prop;
for (prop in req.body) {
ticket[prop] = req.body[prop];
}
Ticket.updateAsync({_id: req.params.id}, ticket)
.then(function(updatedTicket) {
return res.json({'status': 'success', 'ticket': updatedTicket})
})
.catch(function(e) {
return res.status(400).json({'status': 'fail', 'error': e});
});
})
// DELETE a Ticket
.delete(function(req, res, next) {
Ticket.findByIdAndRemoveAsync(req.params.id)
.then(function(deletedTicket) {
res.json({'status': 'success', 'ticket': deletedTicket});
})
.catch(function(e) {
res.status(400).json({'status': 'fail', 'error': e})
});
});
module.exports = router;
// Users Route
const express = require('express');
const router = express.Router();
const User = require('../models/user');
router.route('/')
// READ all users.
.get(function(req, res, next) {
User.findAsync({})
.then(function(users) {
res.json(users);
})
.catch(next)
.error(console.error);
})
// CREATE new user.
.post(function(req, res, next) {
let user = new User();
let prop;
for (prop in req.body) {
user[prop] = req.body[prop];
}
user.saveAsync()
.then(function(user) {
console.log('success');
res.json({'status': 'success', 'user': user});
})
.catch(function(e) {
console.log('fail');
res.json({'status': 'error', 'error': e});
})
.error(console.error);
});
router.route('/:id')
// READ a single User by ID
.get(function(req, res, next) {
User.findOne({_id: req.params.id}, {})
.populate('tickets')
.exec(function (e, user) {
if (e) return console.error(e);
res.json(user);
})
})
// UPDATE a User
.put(function(req, res, next) {
let user = {};
let prop;
for (prop in req.body) {
user[prop] = req.body[prop];
}
User.updateAsync({_id: req.params.id}, user)
.then(function(updatedUser) {
return res.json({'status': 'success', 'user': updatedUser})
})
.catch(function(e) {
return res.status(400).json({'status': 'fail', 'error': e});
});
})
// DELETE a User
.delete(function(req, res, next) {
User.findByIdAndRemoveAsync(req.params.id)
.then(function(deletedUser) {
res.json({'status': 'success', 'user': deletedUser});
})
.catch(function(e) {
res.status(400).json({'status': 'fail', 'error': e})
});
});
module.exports = router;

Resources