mongoose not removing objects - javascript

Folks, for some reason this method is not letting me delete a user by email.
I have tested the functions calling this method, and they are in fact being executed.... thoughts?
var deleteUser = function (emailAddress, callback) {
Users.find({ email:emailAddress }).remove( callback );
}
all of code:
var Users = require('./mongo/users').Users;
var deleteUser = function (emailAddress, callback) {
Users.find({ email:emailAddress }).remove( callback );
}
./mongo/users.js:
var mongoose = require('mongoose');
var Schema = require('mongoose').Schema;
var UserSchema = new Schema({
email: {
type: String,
index: true
},
token: {
type: String,
index: true
},
password: String,
uid: {
type: String,
index: true
},
firstName: String,
lastName: String,
roles: Array
});
UserSchema.statics.findByEmail = function (email, callback) {
this.find({
email: new RegExp(email, 'i')
},
callback)
}
var Users = mongoose.model('users', UserSchema);
module.exports = {
Users: Users
}

Related

How to find documents based on the result of a function mongoose

So I have two schemas user and driver they both have latitude and longitude attributes.
At some point I want to query the database for nearby drivers, I will be sending the user's current location (latitude and longitude) and I have a function to calculate the distance between two points.
I am trying to do something like this:
find all drivers with distance less than 2 KM using my function ( the function is called calculateDistance).
In code this will be like this:
const drivers = await Driver.find();
const driversToReturn = drivers.filter(
driver => calculateDistance(userLat, userLong, driver.latitude, driver.longitude) <= 2
);
res.status(200).json({
drivers: driversToReturn
});
but I don't think this is the best way to do it, I've checked the mongoose virtuals but we can't pass params (userLat and userLong) to the get method of a virtual and I don't think instance methods are the solution.
so how should I do this?
Thanks
EDIT
Driver Model
const mongoose = require("mongoose");
const { Schema } = mongoose;
const driverSchema = new Schema(
{
/** Required Attributes */
name: { type: String, required: true },
carBrand: { type: String, required: true },
plateNumber: { type: String, required: true },
password: { type: String, required: true },
phoneNumber: { type: Number, required: true },
price: { type: Number, required: true },
latitude: { type: Number, required: true },
longitude: { type: Number, required: true },
/** Not Required Attributes */
rating: { type: Number, required: false },
},
{
timestamps: true,
}
);
const Driver = mongoose.model("Driver", driverSchema);
module.exports = Driver;
User Model
const mongoose = require("mongoose");
const { Schema } = mongoose;
const userSchema = new Schema(
{
/** Required Attributes */
name: { type: String, required: true },
password: { type: String, required: true },
phoneNumber: { type: Number, required: true },
latitude: { type: Number, required: true },
longitude: { type: Number, required: true },
},
{ timestamps: true }
);
const User = mongoose.model("User", userSchema);
module.exports = User;
Users Controller
const Driver = require("../models/driver");
const Order = require("../models/order");
const calculateDistance = require("../utils/calculateDistance");
const CIRCLE_RADIUS_IN_KM = 2;
exports.getNearbyDrivers = async (req, res, next) => {
try {
const userLat = req.body.userLat,
userLong = req.body.userLong,
drivers = await Driver.find();
const driversToReturn = drivers.filter(
(driver) =>
calculateDistance(
userLat,
userLong,
driver.latitude,
driver.longitude
) <= CIRCLE_RADIUS_IN_KM
);
res.status(200).json({
drivers: driversToReturn,
});
} catch (err) {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
}
};
Here is some code from the documentation of Mongoose that can help you with that I think :
const denver = { type: 'Point', coordinates: [-104.9903, 39.7392] };
return City.create({ name: 'Denver', location: denver }).
then(() => City.findOne().where('location').within(colorado)).
then(doc => assert.equal(doc.name, 'Denver'));
and here is the link : https://mongoosejs.com/docs/geojson.html

How can I use function getPublicFields with populate mongoose?

Here is the function getPublicFields in User Schema
User Schema
UserSchema.methods.getPublicFields = function () {
var returnObject = {
firstName: this.firstName,
lastName: this.lastName,
email: this.email,
_id: this._id,
};
return returnObject;
};
here just I connect the User Schema with the product and they gave me all the user Data watch I don't want
productController.Js
exports.getProducts = async (req, res, next) => {
try {
const products = await Product.find().populate("owner");
res.status(200).send(products);
} catch (e) {
next(e);
}
};
Product Schema
var mongoose = require("mongoose");
var { Schema } = mongoose;
const ProductSchema = new Schema({
title: {
type: String,
},
category: {
type: String,
},
price: {
type: Number,
},
completed: {
type: Boolean,
default: false,
},
owner: {
ref: "User",
type: mongoose.Schema.Types.ObjectId
},
img: {
type : Array,
}
});
module.exports = mongoose.model("Product", ProductSchema);
populate will give you a plain object, not a Mongoose instance. What you can do is construct a User instance from it:
const user = new User(product.owner);
product.owner = user.getPublicFields();

How do I add new object or push into array Mongodb Compass NodeJS Express (update is not a function)?

At this moment I try to find the query which works in this case, but then want to update the object. So I want to check if review object exist and if not then create that key name first and then push that object into an array. Else push into that in existing object of array.
Default object looks like (without review object):
const mongoose = require('mongoose');
const musicSchema = mongoose.Schema({
id: {
type: Number,
required: true
},
artist: {
type: String,
required: true
},
title: {
type: String,
required: true
},
release_year: {
type: Number,
required: true
},
genre_id: {
type: Number,
required: true
},
image_url: {
type: String,
required: true
},
reviews: [{
id: {
type: Number,
required: true
},
locale: {
type: String,
required: true
},
rating: {
type: Number,
required: true
},
comment: {
type: String,
required: true
}
}]
});
const Music = mongoose.model("Music", musicSchema); // now we have to create our model
console.log;
module.exports = Music; // export our created model
app.post('/addReview/:id', async (req, res) => {
let idNumber = parseInt(req.params.id); // 501437
let reviewObject = req.body; // {id: "501437", locale: "nl", rating: 3, text: "helello"}
try {
const music = client.db('database').collection('music');
const query = { id: idNumber };
const musicSong = await music.findOne(query);
await musicSong.update({ $push: { reviews: reviewObject } }); // error comes from here
} catch (err) {
console.log(err);
}
});
check if reviews field is not exists then initialise it to blank array
push object to reviews
save() to save main document
app.post('/addReview/:id', async (req, res) => {
let idNumber = parseInt(req.params.id); // 501437
let reviewObject = req.body; // {id: "501437", locale: "nl", rating: 3, text: "helello"}
try {
const music = client.db('database').collection('music');
const query = { id: idNumber };
let musicSong = await music.findOne(query);
if (!Array.isArray(musicSong.reviews)) {
musicSong.reviews = [];
}
musicSong.reviews.push(reviewObject);
music.save();
} catch (err) {
console.log(err);
}
});
Second option using updateOne():
It does not require to find, check and save operations if you use update methods,
app.post('/addReview/:id', async (req, res) => {
const query = { id: parseInt(req.params.id) };
let reviewObject = req.body;
try {
const music = client.db('database').collection('music');
await music.updateOne(query, { $push: { reviews: reviewObject } });
} catch (err) {
console.log(err);
}
});

Express.js & mongoose: set default value with bdhash (async)

How can I set default value (like bdhash which is async) to one field in my mongoose schema?
Now I see only promise inside. But why? Seems that I'm using async/await in a right way. Also I tried to do this in a hook ('validate')
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
bcrypt = require('bcrypt');
hashIt = async () => {
let pwd = new Date();
pwd = pwd.toUTCString() + Math.random();
return await bcrypt.hash(pwd, Number(process.env.SALT_WORK_FACTOR));
};
const businessSchema = new mongoose.Schema(
{
name: {
type: String,
trim: true,
unique: 'Please enter a unique business name',
required: 'Please enter a business name'
},
salt: {
type: String,
trim: true,
default: () => {
return hashIt();
},
required: 'Please enter a business salt'
},
created: {
type: Date,
default: Date.now
}
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
);
/* Also tried this way
businessSchema.pre('validate', next => {
if (this.salt) {
return next();
}
this.salt = hashIt();
next();
}); */
module.exports = mongoose.model('Business', businessSchema);
Is it possible to do? And how? The best way :)
see http://mongoosejs.com/docs/defaults.html
Check this example :
var schema = new Schema({
title: String,
genre: {type: String, default: 'Action'}
});
var Movie = db.model('Movie', schema);
var query = {};
var update = {title: 'The Terminator'};
var options = {
// Create a document if one isn't found. Required
// for `setDefaultsOnInsert`
upsert: true,
setDefaultsOnInsert: true
};
Movie.
findOneAndUpdate(query, update, options, function (error, doc) {
assert.ifError(error);
assert.equal(doc.title, 'The Terminator');
assert.equal(doc.genre, 'Action');
});

Mongoose - how to determine whether a nested object already exist in a query?

My database stores a User, which has an array of watchMovies[] containing a nested object movie.
When receiving an update/put API request, containing a watchedMovie object, I want to check whether the movie with id = zzz already exist in the watchedMovie[] array.
The problem is, this query doesn't do it. What am I doing wrong?
User.find(
{ username: req.params.username, 'watchedMovies.movie.id': movie.id },
function (err, count) {
if (!err) exist = true;
}
);
Full code below:
Schema
var userSchema = new Schema({
username: { type: String, require: true },
firstName: String,
lastName: String,
...
watchedMovies : [{
movie: { type: Schema.Types.ObjectId, ref: 'Movie' },
time: Date,
watchedDuration: Number,
}],
})
JSON request body
{
"id": "10-things-i-hate-about-you", //movie id
"time": "2012-05-29T17:57:30.169Z",
"watchedDuration": "88"
}
Mongoose query
router.put('/:username/watchedMovies', function (req, res, next) {
//find movie
Movie.findOne({ id: req.body.id }, function (err, movie) {
if (err) res.send(err);
//find if user already has the movie in the watchedMovies list
var exist = false;
User.find(
{ username: req.params.username, 'watchedMovies.movie.id': movie.id },
function (err, count) {
if (!err) exist = true;
}
);
//if movie is already in watchedList, update User with it
if (exist) {
//set existing watchedMovie object
User.update(...$set...)
} else { // push new
User.findOneAndUpdate(...$push...)
}
});
});
i think this is problem , this is your model
var userSchema = new Schema({
username: { type: String, require: true },
firstName: String,
lastName: String,
...
watchedMovies : [{
movie: { type: Schema.Types.ObjectId, ref: 'Movie' },
time: Date,
watchedDuration: Number,
}],
})
but your query is
{ username: req.params.username, 'watchedMovies.movie.id': movie.id }
dont use movie.id
try this
{ username: req.params.username, 'watchedMovies.movie': movie.id }

Categories