Mongoose not returning, but mongo shell is - javascript

I'm using mongoose on my node app, and I want to get a seller by its email:
getSellerByEmail : function(email,next){
var Seller = mongoose.model('Seller');
console.log(inspect(email));
Seller.findOne({'email' : new RegExp(email, 'i')}, function(seller){
next(seller);
});
}
When I try to login, mongoose does not return the new user. But when I try to create another user with the same email, the server executes this function correctly and it returns the new user.
Also tried with {'email' : email} and It returns null, but when I do this query on mongo shell, it returns correctly.
db.sellers.findOne({email : 'email#email.email'});
{
"_id" : ObjectId("54b94759b042bdbf19cb7b97"),
"name" : "Nome da Empresa",
"cnpj" : "123123123",
"email" : "email#email.email",
"password" : "$2a$08$6UvW8Bux3CwUMok8ac12Sehbd.xCHnVUI51ZwhtGKBjkSa6/MrqUu",
"__v" : 0
}
I'm new to mongodb + mongoose, so I know it's a dumb question, but I just can't realize what is wrong... I've also created a findSellerById() function, and it works perfectly.
EDIT 1:
Using Mongoose debug, here's what it's printed:
Mongoose: sellers.findOne({ email: 'email#email.email' }) { fields: undefined }
Mongoose: sellers.findOne({}) { fields: undefined }
As you can see, also tried with no parameters, no success...

I had the same problem, maybe you could try this:
Seller.find({email: seller.email}, function(err, seller){
console.log(seller);
});
This solved mine, hope it will solve yours too !

The callback function passed into findOne takes two parameters (error and doc), so you're treating seller as the error parameter instead of the doc parameter.
So your function should look like this instead:
getSellerByEmail : function(email,next){
var Seller = mongoose.model('Seller');
console.log(inspect(email));
Seller.findOne({'email' : new RegExp(email, 'i')}, function(err, seller){
next(seller);
});
}

Related

Deleting an element from an Array, that is inside an Object

In my To-Do app, when a logged-in User completes a task, I would like to clear it from the MongoDB database.
Here is the code for my Schema.
const user = new mongoose.Schema({
username : String,
password : String,
task : [{
text : String,
day : String,
reminder : Boolean,
]}
})
For example, if Daryl completed text : "Gym" & day : "Feb 4th 5.30pm", I would like to only remove task[0] from Daryl's task Array.
Here is my attempt at doing so using Mongoose,
app.delete("/tasks", (req,res) => {
User.findOne( {_id : req.user.id}).then((target) => {
target.task.remove({text : req.body.text, day : req.body.day})
})
})
User.findOne({_id : req.user.id}) to only target the person that logged in
Once targeted, access task array using .task
and use .remove along with filters, to remove that entry from the array
I have console.logged() all the variables and it tallies with the data fields, however the entry is not being removed. What am I doing wrong?
I managed to solve my problem, hopefully this helps someone else
app.delete("/tasks", (req, res) => {
User.findByIdAndUpdate(req.user.id, {$pull: {"task": {text: req.body.text}}}, {safe: true, upsert: true},
function (err, node) {
// console.log here for debugging, if you want
})
})
This successfully erases items based on
req.user.id
"task" : {//whatever your stricter conditions are}
I still don't understand why my earlier attempts failed, but at least this one works.

Update database entry using mongoose

Hello i am using mongoose.
I have built this query that finds my desired project :
const projects = await ClientManagers.findOne({'project.contactPerson.work_email' : 'testing#email.com'} , { 'project.$.companyName': 1 });
this returns an object from my database like this :
{
'projectName' : 'x',
'companyName' : 'x bv'
}
How can i update the company name to be 'Y bv' instead of 'x bv'.
Assuming this is your document structure,
{
"_id" : ObjectId("5f2ae5a4b1549ac0460920dd"),
"projectName" : "A",
"project" : [
{
"companyName" : "T1",
"contactPerson" : {
"work_email" : "t1#gmail.com"
}
},
{
"companyName" : "T2",
"contactPerson" : {
"work_email" : "t2#gmail.com"
}
}
]
}
Single Update updateOne()
If you know email will be unique and want to update single document then use updateOne().
first is query part to find condition, email t1#gmail.com
second is set/update part, here $ is for array because project is an array, update companyName to T1 Company
await ClientManagers.updateOne(
{ 'project.contactPerson.work_email': 't1#gmail.com' },
{
$set: { "project.$.companyName": "T1 Companmy" }
}
)
Multiple Update updateMany()
If email is not unique and want to update everywhere then use updateMany(), it will update every matching documents.
await ClientManagers.updateMany(
{ 'project.contactPerson.work_email': 't1#gmail.com' },
{
$set: { "project.$.companyName": "T1 Company" }
}
)
Not suggesting update() method to use, because its deprecated in mongoose and will give Deprecation Warnings
, this function is replaced with updateOne(), updateMany() and replaceOne() methods.
Good start. Mongo has better documentation with examples. I suggest you to refer that also.
use update
db.collection.update({companyName:'x bv'}, {"$set":{"companyName":y}})
Mongo is case sensitive. So name should match exactly.
update updates one document. To update multiple, use updateMany or multi:true option with update or findOneAndMondify for one update for find and update case.

Mongoose cast to ObjectID failed for value... but why

I know what the problem is, but can't figure out why it is happening. I have a simple recipe app using express and mongoose. User passes in recipe info via form and is saved to database via mongoose methods. This part seems to work perfectly and when I console.log using test data, I see that the following data is saved:
{
ingredients: [ 'peanut butter', 'jelly', 'bread' ],
_id: 5e47d564f775ce247052d01c,
name: 'pb jelly sammich',
author: 'rob',
oneLiner: 'classic pb jelly sammich',
image: 'picofpbsammich here',
method: 'add all the ingredients together and boom! pb jelly sammich.',
__v: 0
}
(This is also what shows when I check mongo db using db.recipes.find() and also what displays when I pass in the object to my ejs show template.
However, when I access my show route via get request, I get a long error message using the above test data. Here is they key part of the error message:
'Cast to ObjectId failed for value "picofpbsammich here" at path "_id" for model "Recipes"',
I understand what the problem is, but baffled as to why it is happening. Here is my show route:
app.get("/recipes/:id", function (req, res) {
console.log(req.params.id)
Recipe.findById(req.params.id, function (err, foundRecipe) {
if (err) {
console.log(err);
} else {
res.render("show", { recipe: foundRecipe });
}
})
})
console logging the req.params.id as shown above, prints the following:
5e47d564f775ce247052d01c
picofpbsammich here
The first line is the correct ID, the second is obviously not and the cause of the problem, but I have no idea where that could be coming from :S Why would req.params.id be pulling the VALUE of a property that is named something completely different?
I'm new to mongoose so it's probably something silly I'm doing and any explanations appreciated.
Here is the model:
var mongoose = require("mongoose");
let recipeSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
author: String,
oneLiner: String,
ingredients: [String],
image: String,
method: String
})
module.exports = mongoose.model("Recipes", recipeSchema)
You posted the following code:
app.get("/recipes/:id", function (req, res) {
console.log(req.params.id)
Recipe.findById(req.params.id, function (err, foundRecipe) {
if (err) {
console.log(err);
} else {
res.render("show", { recipe: foundRecipe });
}
})
})
And you mention that in the console.log you receive:
5e47d564f775ce247052d01c
picofpbsammich here
Followed by the exception being logged:
'Cast to ObjectId failed for value "picofpbsammich here" at path "_id"
for model "Recipes"',
Makes me logically assume that you are making two requests, one of which the id is not valid, being:
picofpbsammich here
Mongoose is not able to cast this value to an ObjectId, hence you get the exception, which makes sense imo.

Sequelize "WHERE" Clause in subqueries

I'am trying to build my query using sequelize, in the where clause I need to give the conditional value from my front-end so i did it like this :
getResults(req) {
return parm
.findAll({
attributes: [
sequelize.literal('DISTINCT "id"')
],
where : {
name: req.query.parm.replace(/"/g, '').split(',')
} ,
raw: true
});
}
and it's working!
but now I need to write a subquery including where clause:
something like this :
SELECT tab1.name FROM
(SELECT name FROM "MYTABLE"
WHERE id = (value from the front-end) AND name IN (values from front-end)
) as tab1
Here is what i have tried :
getTest(req) {
if (req.query.parm != null) {
return parm .sequelize.query('SELECT id FROM "table_base" where id = $mid ); ',
{ type: sequelize.QueryTypes.SELECT ,
bind: { mid: [req.query.parm.replace(/"/g, '').split(',')] }} );
}
},
i tried to use raw query and i tested the binding parameters but i get this error when i execute this testing query :
Executing (default): SELECT id FROM "table_base" where id = $1 );
The answer to your question is YES it is indeed possible! SQL can pretty much do anything even if you are using sequelize. If you write the subquery and it doesn't work just post it back here so people can take a look and debug. Thanks

Mongodb/Mongoose: Storing Subdocument of a Variable to a Variable

I am trying to create a shotgun npm command for deleting all topics ever created by a user
This is a sample user entry (users are stored in a collection called 'users'):
{
"__v" : 0,
"_id" : ObjectId("536c4c8fafec055606f01840"), //the id I want to store to a variable and use the variable to find all topics with that id in the 'creator' document
"joinDate" : ISODate("2014-05-09T18:13:28.079Z"),
"lastActiveDate" : ISODate("2014-05-09T18:13:48.918Z"),
"lastSocketId" : null,
"password" : "Johndoe6",
"roles" : [],
"username" : "johndoe6"
}
This is a sample topic entry (topics are stored in a collection called 'topics'):
{
"__v" : 4,
"_id" : 202, //unreliable as these change all the time
"body" : "example topic text",
"commentCount" : 0,
"creator" : ObjectId("536c4c8fafec055606f01840"), //this is the id I want to be found with my variable from a found user
"date" : ISODate("2014-05-14T13:58:13.668Z"),
"editedBy" : ObjectId("536f0392ca01fb0e39364c02"),
"editedDate" : ISODate("2014-05-14T13:59:27.607Z"),
"lastCommentDate" : ISODate("2014-05-14T13:58:13.670Z"),
"tags" : [],
"title" : "test",
"views" : [],
}
Here is a snippet of my code:
exports.invoke = function (shell, options) {
if (!options.confirm) {
shell.warn("Are you sure you want to delete all topics made by {{0}}? (Y/N)".format(options.username));
return shell.setPrompt('confirm', 'purgeTopic', options, 'Are you sure?');
}
shell.db.User.findOne({ username: options.username }, function (err, user) {
var userid = something //this is where I want it to pluck out the user's ID and store it for later
if (err) return shell.error(err);
if (!user) return shell.error("No user {{0}} exists.".format(options.username));
//otherwise
shell.db.Topic.where('creator').equals(userid).remove(function (err) {
As you can see, options.username is a variable that has been typed in by the user doing the command. On the last line I want it to remove topics that have a subdocument 'creator' with the id of the 'user'. How can this be accomplished?
It would simply be:
var userid = user._id;
But you'd want to put that after your if (!user) check in case user is null.

Categories

Resources