Mongoose, push an array Model.update is not a function - javascript

mongoose categorySchema:
const CategoryAdvertSchema = new mongoose.Schema({
UniqueHomes: {
cave: { type: Boolean, default: false },
natureLodge: { type: Boolean, default: false },
castle: { type: Boolean, default: false },
farmStay: { type: Boolean, default: false }
},
PropertyType: {
apartment: { type: Boolean, default: false },
villa: { type: Boolean, default: false },
loft: { type: Boolean, default: false },
yurt: { type: Boolean, default: false }
},
Others: [CategoryDynamiqueSchema]
});
My mongoose OthersShema for push array:
const CategoryDynamiqueSchema = new mongoose.Schema({
dayOfCategory: { type: Date, default: Date.now },
nameOfCategory: { type: String },
typeOfCategory: { type: String }
});
My API:
category.post('/category', jwt.checkUserToken, (req, res) => {
const dayOfCategory = Date.now();
const nameOfCategory = req.body.nameOfCategory;
const typeOfCategory = req.body.typeOfCategory;
CategoryAdvert.update({
$push: {
Others: {
dayOfCategory: dayOfCategory,
nameOfCategory: nameOfCategory,
typeOfCategory: typeOfCategory
}
}
}, { new: true }, (err, category) => {
if (err) {
res.json({ success: false });
console.log('err : ', err);
} else {
console.log("La catégorie '" + nameOfCategory + "' a bien été ajouté");
res.json({ success: true });
}
});
});
When I try to push an array I get the following error:
TypeError: CategoryAdvert.update is not a function

i have make light change and it's working
category.post('/category', jwt.checkUserToken, (req, res) => {
console.log('req.body => ', req.body);
const dayOfCategory = Date.now();
const nameOfCategory = req.body.nameOfCategory;
const typeOfCategory = req.body.typeOfCategory;
Advert.update({
$push: {
'CategoryAdvert.Others': {
dayOfCategory: dayOfCategory,
nameOfCategory: nameOfCategory,
typeOfCategory: typeOfCategory
}
}
}, { new: true }, (err, category) => {
if (err) {
res.json({ success: false });
console.log('err : ', err);
} else {
console.log("La catégorie '" + nameOfCategory + "' a bien été ajouté");
res.json({ success: true });
}
});
});

Related

How would I populate the mongoDB post schema with all comments for post?

I have build two schemas, one for posts and one for comments.
const PostSchema = new Schema(
{
title: { type: String, required: true },
text: { type: String, required: true },
author: { type: Schema.Types.ObjectId, ref: 'User', required: true },
status: { type: Boolean, default: true },
},
{ timestamps: true }
);
, and:
const CommentSchema = new Schema(
{
text: { type: String, required: true, minlength: 5 },
author: { type: String, required: true },
post: { type: Schema.Types.ObjectId, ref: 'Post' },
},
{
timestamps: true,
}
);
Now I want to make a GET request which finds all posts and would populate each post with its comments. So far I have this, but I am hitting a wall. If I try to do it like this, I can't add .toArray(), and it doesn't even add new field to the allPosts.
exports.allPosts_GET = (req, res) => {
Post.find()
.populate('author')
.sort('-createdAt')
.exec((err, allPosts) => {
if (err) {
return res.status(500).json({ success: false, msg: err.message });
} else if (allPosts.length === 0) {
return res.status(404).json({
success: false,
msg: 'No posts find in the database!',
});
}
allPosts.map((post) => {
post.comments = Comment.find({post: post._id}).
//to array somehow and populate all posts
});
console.log(allPostsStore);
res.status(200).json({ success: true, posts: allPosts });
});
};
So I came up with a solution, I updated my Post schema that contains an array with reference to ids of comments. Like that:
const PostSchema = new Schema(
{
title: { type: String, required: true },
text: { type: String, required: true },
author: { type: Schema.Types.ObjectId, ref: 'User', required: true },
comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
status: { type: Boolean, default: true },
},
{ timestamps: true }
);
And then when you make a new comment, you reference it to a post, and also save it to array of comments, like that:
exports.createNewComment_POST = (req, res) => {
const { text, author, postID } = req.body;
const newComment = new Comment({
text,
author,
post: postID,
});
newComment
.save()
.then((comment) => {
Post.findByIdAndUpdate(
postID,
{ $push: { comments: comment._id } },
{ new: true, useFindAndModify: false },
(err, post) => {
if (err) {
return res.status(500).json({ success: false, msg: err.message });
}
res.status(200).json({ success: true, comment });
}
);
})
.catch((err) => {
res.status(500).json({ success: false, msg: err.message });
});
};
Getting all posts with their comments, you just use find() and populate(), like that:
exports.allPosts_GET = (req, res) => {
Post.find()
.populate('author', '-password')
.populate('comments')
.sort('-createdAt')
.exec((err, posts) => {
if (err) {
return res.status(500).json({ success: false, msg: err.message });
} else if (posts.length === 0) {
return res.status(404).json({
success: false,
msg: 'No posts find in the database!',
});
}
res.status(200).json({ success: true, posts: posts });
});
};

Find One and Update in Mongoose with reference to other models is not working

I have a model named OrderModel and it has reference to other models as well
const orderSchema = new Schema({
_id: Schema.Types.ObjectId,
address: { type: addressSchema, required: false },
items: [{ type: Schema.Types.ObjectId, ref: 'Items' }],
date: { type: Date, default: moment(new Date()) },
user: { type: Schema.Types.ObjectId, ref: 'Users' },
is_completed: { type: Boolean, required: true, default: false },
is_canceled: { type: Boolean, required: true, default: false }
});
and when I want to update this model, using PATCH, it is giving me an error,
CastError: Cast to [ObjectId] failed for value "["5f0c9493f833e23a0028bd31,5f0c9429f833e23a0028bd2f"]" at path "items"
Here is how I do it in my code,
router.patch('/order', (req, res) => {
const query = { _id: req.body._id };
const _token = req.headers.authorization;
let data = req.body;
jwt.verify(_token, process.env.AUTH_TOKEN_KEY, (err, decoded) => {
console.log(query);
if (err) {
res.json({ message: 'Token Invalid'.err });
} else {
OrderModel.findOneAndUpdate(query, data, { new: true }, (err, doc) => {
console.log(doc,query);
if (doc) {
return res.json({ message: 'Succesfully saved', data: doc });
}
return res.json({ message: `No order found for id ${req.body._id}` });
});
}
})
})
i have two items as an Array, sent from frontend
{
"_id": "5f8f1b7b29cbed4a8495d646",
"items":"5f0c9493f833e23a0028bd31,5f0c9429f833e23a0028bd2f",
"user":"5f06060110b7881ac0244005",
"address":{
"line_1": "Address line 1",
"line_2": "Address line 1",
"city": "Los Angeles",
"state": "California",
"pin": "90210"
},
"is_completed": false,
"is_canceled": false
}
what am i doing wrong here?

sequelize validate multiple column [this.column got undefined]

hi guys I have some problems, why this.day_number and this.teacher_id is undefined?
'use strict'
module.exports = (sequelize, DataTypes) => {
const Teacher = sequelize.models.teachers
const TimeSlot = sequelize.define('time_slots', {
day: {
type: DataTypes.STRING,
validate: {
notEmpty: {
msg: 'Hari harus diisi.'
},
isIn: {
args: [['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu']],
msg: "Hari tidak tersedia."
}
}
},
day_number: {
type: DataTypes.TINYINT,
validate: {
notEmpty: {
msg: 'Urutan hari harus diisi.'
},
isInt: {
msg: 'Urutan hari harus berupa angka.'
},
isIn: {
args: [[0, 1, 2, 3, 4, 5, 6]],
msg: "Urutan hari tidak tersedia."
}
}
},
time: {
type: DataTypes.TIME,
validate: {
notEmpty: {
msg: 'Waktu mulai harus diisi.'
},
isExists: (value, next) => {
TimeSlot.findOne({
where: {
time: value,
day_number: this.day_number,
teacher_id: this.teacher_id
},
attributes: ['id']
})
.then((data) => {
if (data) {
return next('Waktu mengajar sudah digunakan.')
}
next()
})
.catch((err) => {
next(err)
})
}
}
},
teacher_id: {
type: DataTypes.STRING,
validate: {
notEmpty: {
msg: 'Guru belum dipilih.'
},
isExists: (value, next) => {
Teacher.findOne({
where: {
id: value
},
attributes: ['id']
})
.then((data) => {
if (!data) {
return next('Guru tidak tersedia.')
}
next()
})
.catch((err) => {
next(err)
})
}
}
}
}, {
timestamps: true,
freezeTableName: true,
updatedAt: 'updated_at',
createdAt: 'created_at'
})
TimeSlot.associate = (models) => {
TimeSlot.belongsTo(models.teachers, {
foreignKey: 'teacher_id',
onDelete: 'CASCADE',
as: 'teacher'
})
}
return TimeSlot
}
You're using arrow functions and arrow functions don't bind this.(MDN - Arrow functions)
Replace all arrow functions like the code below.
isExists(value, next) {
TimeSlot.findOne({
where: {
time: value,
day_number: this.day_number,
teacher_id: this.teacher_id
},
attributes: ['id']
})
.then((data) => {
if (data) {
return next('Waktu mengajar sudah digunakan.')
}
next()
})
.catch((err) => {
next(err)
})
}

No matching document found for id error

I am facing two issues with the below code
Upon saving the document after put API call,it's throwing a message ' No matching document found for id \"59c6607a1608fe26e8c7f574\"" '
If required attribute value for each field is set as true then mongoose is throwing a validation error message stating that path not found.For eg if ii set addressLine1: { type: String, required: true } then it throws a validation message contact.addressLine1: Path contact.addressLine1 is required.However if required attribute is set to false then no validation error is thrown.
Can some one help me to correct the below code -
Model -
var localTransportSchema = new Schema({
providerID: {
type: Number,
required: true,
trim: true,
unique: false
},
name: {
type: String,
required: true,
trim: false
},
contact: {
addressLine1: {
type: String,
required: false
},
addressLine2: {
type: String,
required: false
},
city: {
type: String,
required: false
},
postalCode: {
type: Number,
required: false
},
primaryContactNumber: {
type: Number,
required: false
},
secondaryContactNumber: {
type: Number,
required: false
},
serviceActiveFlag: {
type: String,
required: false,
enum: ['Y', 'N']
},
},
vehicle: [{
vehicleType: {
type: String,
required: false,
enum: ['sedan', 'hatchback', 'suv', 'mpv', 'luxury']
},
activeFlag: {
type: String,
required: false,
enum: ['Y', 'N']
},
}]
});
Controller -
module.exports.updateLocalTransportVendorDtls = function(req, res) {
var transportSchema = new transportModel();
new Promise(function(resolve, reject) {
checkForNewVehicleType(req, function(doc) {
resolve(doc)
})
})
.then(function(doc) {
var updateJustServiceDtls = doc.split(/\|/)[2];
return addJustNewVehicleDetailsOnly(req, res)
}).then(function() {
transportSchema.save(function(error) {
if (error) {
logger.error("Error while updating record in transport details collection: - " + error.message)
return res.status(500).json({
"Message": error.message.trim()
});
}
})
}).catch(function(err) {
return res.json({
"Message": err.message
});
});
}
Function -
var addJustNewVehicleDetailsOnly = function(req, res) {
var promise = new Promise(function(resolve, reject) {
var updates = {
$set: {
"contact": {
"addressLine2": req.body['addressLine2'],
"secondaryContactNumber": req.body['secondaryContactNumber'],
"serviceActiveFlag": req.body['serviceActiveFlag']
},
"$push": {
"vehicle": {
"vehicleType": req.body['vehicleType'],
"chargePerKiloMeter": req.body['chargePerKM'],
"selfDriven": req.body['isSelfDriven'],
"additionalCharges": req.body['additionalCharges'],
"driverBata": req.body['driverBata'],
"activeFlag": req.body['vehicleActiveFlag']
}
}
}
}
transportModel.findOneAndUpdate({
"name": req.body['providerName'],
"contact.postalCode": parseInt(req.body['postalCode'])
},
updates, {
returnOriginal: false,
upsert: false
},
function(err, doc) {
if (err) {
logger.error("Error while updating record : - " + err.message);
return reject(res.status(409).json({
"Message": "Error while updating transport details for provider " + req.body['providerName'] + " in transport details table"
}));
} else if (doc === null) {
logger.error("Error while updating record in transport details : - unable to update database");
return reject(res.status(409).json({
"Message": "Error while updating transport details for provider " + req.body['providerName'] + " due to " + err.message
}));
}
return resolve();
});
})
return promise;
}

Express, Mongoose - .update() is returning null

When I am trying to update a document in my model, the .update() is returning null but the .find() method works fine.
module.exports.updateBio = function(req, res) {
var userID = req.params.id;
var objForUpdate = {};
if (!troolr.isEmptyString(req.body.profile_picture)) objForUpdate.profile_picture = req.body.profile_picture;
if (!troolr.isEmptyString(req.body.title)) objForUpdate.title = req.body.title;
if (!troolr.isEmptyString(req.body.intro)) objForUpdate.intro = req.body.intro;
if (!troolr.isEmptyString(req.body.summary)) objForUpdate.summary = req.body.summary;
if (!troolr.isEmptyString(req.body.skills)) objForUpdate.skills = req.body.skills;
if (!troolr.isEmptyString(req.body.facebook)) objForUpdate.social.facebook = req.body.facebook;
if (!troolr.isEmptyString(req.body.twitter)) objForUpdate.social.twitter = req.body.twitter;
if (!troolr.isEmptyString(req.body.linkedin)) objForUpdate.social.linkedin = req.body.linkedin;
if (!troolr.isEmptyString(req.body.website)) objForUpdate.social.website = req.body.website;
var conditions = { "_id": userID }
, setObj = { $set: objForUpdate }
, options = { multi: true };
//This throws error
// Error: { ok: 0, n: 0, nModified: 0 }
Profile.update(conditions, setObj, (err, page) =>{
if(err) throw err;
console.log(page);
});
// This works fine but it erases old values if they are empty
/* Profile.findById(userID, (error, user) => {
if(error) return res.status(500).json({ success: false, error: error });
user.bio = objForUpdate;
user.save(function(error) {
if(error) return res.status(500).json({ success: false, error: error });
return res.status(200).json({ success: true, message: "Bio successfully updated." });
});
}); */
};
// API Endpoint
http://localhost:3000/api/v1/profile/592c53b3bdf350ce004ad717/updatebio
// API Define
'use strict';
/**
* Routes for Profile Model
*
**/
var passport = require('passport');
var jwt = require('jwt-simple');
var settings = require("settings");
var profileCtrl = require(settings.PROJECT_DIR + 'routes/controllers/api/profile');
module.exports = function(app) {
app.get('/all', profileCtrl.getAll);
app.get('/:id', profileCtrl.getSingle);
app.put('/:id/updateurl', profileCtrl.updateURL);
app.put('/:id/updateaddress', profileCtrl.updateAddress);
app.put('/:id/updatebio', profileCtrl.updateBio);
}
// Model
var mongoose = require('mongoose');
// User Schema
var ProfileSchema = mongoose.Schema({
url : {
type: String,
unique: true,
},
fname: {
type: String,
required: true
},
lname: {
type: String,
required: true
},
email: {
type: String,
unique: true,
required: true
},
bio: {
profile_picture: {
type: String
},
title: {
type: String
},
intro: {
type: String
},
summary: {
type: String
},
skills: {
type: Object
},
social: {
linkedin: {
type: String
},
twitter: {
type: String
},
facebook: {
type: String
},
website: {
type: String
}
},
},
location: {
address: {
type: String
},
apt: {
type: String
},
city: {
type: String
},
state: {
type: String
},
zip_code: {
type: String
},
country: {
type: String
}
},
phone: {
type: Number
},
listings: {
type: Object
},
reviews: {
type: Object
},
verfied: {
type: Boolean,
default: false
},
// expires: {
// type: Date,
// expires: '1h',
// default: Date.now
// },
});
var Profile = module.exports = mongoose.model('Profile', ProfileSchema);
module.exports.getUserByEmail = function(email, callback){
var query = {'email': email};
Profile.findOne(query, callback);
}
module.exports.checkIfUrlExists = function(res, url, callback){
var query = {'url': url};
Profile.findOne(query, function(error, found) {
if(error) return res.status(500).json(error);
if(found) return res.status(500).json({success: false, message: "URL already exists" });
if(callback) callback();
});
}
// Document which I am trying to update
{
"_id": "592c53b3bdf350ce004ad717",
"url": "hyoh7ryb-",
"fname": "Foo",
"lname": "Bar",
"email": "foobar#gmail.com",
"__v": 0,
"verfied": false
}
Anything not defined in schema is not saved. That's what happening when you're missing bio key while preparing the objForUpdate to $set:
var objForUpdate = {};
if (!troolr.isEmptyString(req.body.profile_picture)) objForUpdate.profile_picture = req.body.profile_picture;
which should be
var objForUpdate = {
bio: {}
};
if (!troolr.isEmptyString(req.body.profile_picture)) objForUpdate.bio.profile_picture = req.body.profile_picture;
if (!troolr.isEmptyString(req.body.title)) objForUpdate.bio.title = req.body.title;
// and so on
Your save is working because of saving the object in the right keyuser.bio = objForUpdate;

Categories