Mongoose Update - node.js

I can't update the status field in the document. can somebody please help? Thanks!
changing the default value is the issue.
i want the admin to be able to update the status of the applicant from pending to whatever option is chosen from the select options in the ejs form
this is in the controller:
exports.postName = async(req, res, next)=>{
const name = req.body.name;
console.log(name)
const pupil = new Pupil({
name: name,
});
await pupil.save().then(updates=>{
console.log(updates)
res.redirect('/name');
}).catch(error=>{
console.log(error);
});
}
this also is from the controller:
exports.postUpdatePupil = async (req, res, next)=>{
const status = req.body.status
Pupil.updateOne(
{_id: req.params.id},
{
$set: {'Pupil.$.status': status}
},(err, result)=>{
if(err){
return next(err)
}console.log(result);
}
)
this is the model:
const UpdateSchema = new mongoose.Schema({
name: String,
status: {type: String, default: "Pending"}
});
const update = mongoose.model('update', UpdateSchema);
module.exports = update;

Model name should be "Pupil" and not "Update".
const PupilSchema = new mongoose.Schema({
name: String,
status: {type: String, default: "Pending"}
});
module.exports = mongoose.model('Pupil', PupilSchema);
And you update like:
Pupil.updateOne(
{ _id: req.params.id },
status // same as { status: status }
(err, result) => {
if (err) return next(err);
console.log(result);
},
);

Related

Im trying to update a users information using MongoDB and JWT

when I use this code to try and update the user it appears as a server error. Im using JWT and mongodb but am unsure if im pulling the token or the id to update the users information. Below my controller code is attached and my schema.
const updateUser = async (req, res) => {
try {
const user = await User.findByIdAndUpdate(req.user.id)
if(!user) return res.status(400).send({ error: 'User not found'})
Object.assign(user, req.body);
user.save()
res.send({ data: user})
} catch (error) {
res.status(500).send({error: 'Server Error'})
}
}
const mongoose = require('mongoose');
let userSchema = new mongoose.Schema({
name: { type: String, required: true},
email: { type: String, required: true, unique: true},
password: { type: String, required: true},
date: { type: Date, default: Date.now}
})
module.exports = mongoose.model('user', userSchema)
Updated update function but i appear to have an error
const updateUser = async (req, res) => {
try {
const updatedUser = await User.findByIdAndUpdate(req.params.id,req.body)
if(!updatedUser) return res.status(400).send('User cannot be updated!')
res.json(updatedUser)
} catch (error) {
res.status(500).send({error: 'Server Error'})
}
}
Try this :
//update user by id
exports.updateUser = async (req, res) => {
try {
const updatedUser = await
<--req.params.id is the user.id and req.body contains the requested fields to update -->
User.findByIdAndUpdate(req.params.id,req.body)
res.json(updatedUser);
}
catch (err) {
console.log(err);
res.status(500).json({ message: 'Internal server error' });
}
}

Pass a Button value and Update the database

Working on a personal project, one of the functions of the project is to update the user status on what event they are participating.
i wanted to submit a value using a button
<form action="/users/fooddrivebanner" method="POST"><button name="fooddrive" type="submit" value="fooddrive" id="fooddrive">Participate</button></form>
then pass the value to my route and save it inside my database
router.post('/fooddrivebanner', (req,res)=>{
const { fooddrive } = req.body;
const _id = ObjectId(req.session.passport.user._id);
User.findOne({ _id: _id }).then((user)=>{
if (!user) {
req.flash("error_msg", "user not found");
res.redirect("/fooddrivebanner");
}
if (typeof eventparticpating !== "undefined") {
user.eventparticpating = 'fooddrive';
}
user.save(function (err, resolve) {
if(err)
console.log('db error', err)
// saved!
});
})
.catch((err) => console.log(err));
Here is the User model
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
eventparticpating: {
type: String,
default: 'None At The Moment'
}
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
It showed a console error
TypeError: Cannot set property 'eventparticpating' of null
UPDATE
Edit 1:
I followed Mr Gambino instructions, error Gone yet cannot update the database, how would i be able to adjust and find my user?
Instead of saving within the findOne function,you can do this:
router.post('/fooddrivebanner', async (req,res) => {
const { fooddrive } = req.body;
const _id = ObjectId(req.session.passport.user._id);
await User.findOne({ _id: _id }, (error, user) => {
if (error) {
req.flash("error_msg", "user not found");
res.redirect("/fooddrivebanner");
}
}).updateOne({ eventparticpating: "foodrive" });
});
I hope that answers your question

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;

How do you save to three collections at once?

I'm building my first mean stack app. It's a review site that contains three models: User, Review, and Company.
When I make a review, I want the new review to be saved to the 'review' collection, and for that review to be connected by reference to the company being reviewed and the user who wrote the review. I also want the user to hold a reference to the review, and the company to hold a reference to all the reviews it has. Here are my models:
Review
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const reviewSchema = new Schema ({
companyName: String,
companyId: { type: Schema.Types.ObjectId, ref: 'Company'},
starRating: Number,
subject: String,
commentBody: String,
createdBy: { type: Schema.Types.ObjectId, ref: 'User'},
});
const Review = mongoose.model("Review", reviewSchema);
module.exports = Review;
Company
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const companySchema = new Schema ({
companyName: String,
about: String,
basedIn: String,
materialOrigins: [String],
productRange: [String],
category: String,
reviews: [ {type: Schema.Types.ObjectId, ref: 'Review'} ],
socialRating: Number,
environmentalRating: Number,
priceRange: Number
});
const Company = mongoose.model("Company", companySchema);
module.exports = Company;
User
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema ({
email: String,
firstName: String,
lastName: String,
password: String,
image: Object,
aboutText: String,
reviews: [ { type: Schema.Types.ObjectId, ref: "Review" } ]
// comments: { type: Schema.Types.ObjectId, ref: 'Comment' }
});
const User = mongoose.model("User", userSchema);
module.exports = User;
This is my current route, which currently saves the review to the collection and attaches the user. However, the user doesn't get the review.
route
router.post('/:category/:company', (req, res) => {
var subject = req.body.subject;
var commentBody = req.body.commentBody;
var starRating = req.body.starRating;
var userId = req.body.userId;
if(!subject || !commentBody || !starRating) {
res.status(400).json({ message: "Subject, comment body, and star rating are required." });
return;
}
var newReview = Review({
starRating,
subject,
commentBody,
userId
});
User.findById(userId, {
}, (err, user) => {
if (err) {
return res.send(err);
} else {
console.log("checking out user in route", user);
user.reviews.push(newReview);
user.save();
newReview.save((err, review) => {
if (err) {
return res.status(400).json({ message: err });
} else {
res.status(200).json({ message: 'Review saved', review });
}
});
}
});
I haven't tried adding the company in because I'm trying to do one thing at a time. I've been looking at 'populate', but all of the documentation seems to only use two models at once. Is it possible to do three at once? Or am I overcomplicating this?
Apologies if this is all overcomplicated. I'm fairly new to MongoDB and MEAN stack in general. Thanks for your help.
Ok, I did it, for any people landing on this page wondering the same thing in the future.
Here's my route:
router.post('/:category/:company', (req, res, next) => {
var companyName;
var companyId;
var subject = req.body.subject;
var commentBody = req.body.commentBody;
var starRating = req.body.starRating;
var createdBy = req.body.createdBy;
if(!subject || !commentBody || !starRating) {
res.status(400).json({ message: "Subject, comment body, and star rating are required." });
return;
}
var newReview = Review({
starRating,
subject,
commentBody,
createdBy
});
//I need the companyId and companyInfo for later use in my review save. I'm calling the company with the name I have from my params, and setting the id and name with the received data from Mongo.
Company.findOne({"companyName": req.params.company}, (err, company) => {
if (err) {
return res.status(400).json({ message: err });
} else {
this.companyName = company.companyName;
this.companyId = company.id;
}
});
newReview.save((err, review) => {
//Push the review id to the user
if (err) {
return res.status(400).json({ message: err });
} else { User.findByIdAndUpdate({_id: createdBy },{$push: {reviews: review.id} }, (err) => {
if (err) {
console.log("There was an error pushing review to user");
next(err);
//Push the review id to the company
} else { Company.findOneAndUpdate({ "companyName": req.params.company}, {$push: {reviews: review.id}}, (err, company) => {
if (err) {
console.log("There was an error pushing review to company");
next(err);
} else {
//Updates the review by setting companyId and companyName properties to review for Mongo
Review.update({_id: review.id}, {$set: {companyId: this.companyId, companyName: this.companyName}}, (err, changes) => {
if(err) {
return res.status(400).json({message : err});
} else {
console.log("updating review successfully with company info", changes);
}
});
console.log ("Review successfully saved");
res.json({
review: review,
});
}
});
}
});
}
});
});
If anyone has feedback on how this could be done better/more efficiently, let me know. Cheers.

Mongo db, how to give object _id another collection's document

I have 2 collections called User and Location. In User, there is a location _id and this is an Object. Id also references the location collection. My question is what did I do wrong? When I call getUser function I want to see user information and the user's location information. What I need to do ?
User Schema
module.exports = (function userSchema() {
var Mongoose = require('mongoose');
var userSchema = Mongoose.Schema({
name: {
type: String,
require: true
},
surname: {
type: String,
require: true
},
tel: {
type: String,
require: true
},
age: {
type: String,
require: true
},
mevki_id: {
type: String,
require: true
},
location_id: [{
type: Mongoose.Schema.Types.ObjectId,
ref: 'locations'
}]
});
var collectionName = 'users';
var User = Mongoose.model(collectionName, userSchema);
return User;
})();
User Controller
function userController() {
var User = require('../models/UserSchema');
this.createUser = function (req, res, next) {
var name = req.body.name;
var surname = req.body.surname;
var tel = req.body.tel;
var age = req.body.age;
var mevki_id = req.body.mevki_id;
var lok_id = req.body.lok_id;
User.create({
name: name,
surname: surname,
tel: tel,
age: age,
mevki_id: mevki_id,
lok_id: lok_id
}, function (err, result) {
if (err) {
console.log(err);
return res.send({
'error': err
});
} else {
return res.send({
'result': result,
'status': 'successfully saved'
});
}
});
};
this.getUser = function (req, res, next) {
User.find()
.populate('lok_id')
.exec(function (err, result) {
if (err) {
console.log(err);
return res.send({
'error': err
});
} else {
return res.send({
'USERS': result
});
}
});
};
return this;
};
module.exports = new UserController();
First, your schema is wrong:
var userSchema = new Mongoose.Schema({
// ...
location_id: { type: [Mongoose.Schema.Types.ObjectId], ref: 'locations' }
})
Second, in your schema the last field name is location_id while in your controller, you change it to lok_id.
So, fix this:
User.create({
// ...
location_id: lok_id
}
and this:
User
.find()
.populate('location_id')
UPDATE
In your json the last field name is location_id, therefore, fix this too:
this.createUser = function (req, res, next) {
// ...
var lok_id = req.body.location_id;
}

Resources