Reputation: 158
I have a model (AccountModel.js) as below and the controller for it. i tried to change one document using postman but i am getting an empty array from the database event though the data is present.
let mongoose = require('mongoose')
let Schema = mongoose.Schema
var ObjectId = Schema.ObjectId
let mySchema = mongoose.Schema({
account_id:ObjectId,
account_key:String,
message:String,
created_at:Date,
updated_at:Date
})
let MySchema = module.exports =
mongoose.model('account',mySchema);
module.exports.get = function(callback,limit){
MySchema.find(callback).limit(limit)
}
and AccountController as below to manage account db. i have consoled the query and the output from the database.
var mongoose = require('mongoose')
var Account = require('../models/AccountModel')
var ObjectId = mongoose.Types.ObjectId;
exports.setMessage = function(req,res){
query = {account_id:new ObjectId(req.body.acnt_id)}
console.log(query,"...")
Account.find(query,function(err,account_data){
if(err){
res.send(err)
}
else{
try{
console.log(account_data,'setWelcomeMessage')
account_data.message =
req.body.welcomeMessage
account_data.updated_at = new Date()
account_data.save((err,data)=>{
if(err){
console.log(err)
res.send(err)
}
res.send({"Status":"Success"})
})
res.send({"Status":"Success"})
}
catch(e){
//console.log(e)
res.send({"Status":"Failed"})
}
}
})
}
below is the database
> db.account.find().pretty()
{
"_id" : ObjectId("5c18fea5c5a6a4ebf7999c0b"),
"account_id" : ObjectId("5c18fbefc5a6a4ebf7999c08"),
"account_key" : "UDS1500",
"message" : "testing message",
"created_at" : ISODate("2018-12-18T14:05:25.637Z"),
"updated_at" : ISODate("2018-12-18T14:05:25.637Z")
}
{
"_id" : ObjectId("5c18feffc5a6a4ebf7999c0c"),
"account_id" : ObjectId("5c18fbaac5a6a4ebf7999c07"),
"account_key" : "UDS1299",
"message" : "testing message2",
"created_at" : ISODate("2018-12-18T14:06:55.968Z"),
"updated_at" : ISODate("2018-12-18T14:06:55.968Z")
}
after calling from POSTMAN i am getting an empty array
Below is the request format
{
"acnt_id":"5c18fbaac5a6a4ebf7999c07",
"welcomeMessage":"test message 3!!"
}
console is as below
{ account_id: 5c18fbaac5a6a4ebf7999c07 } '...'
[] 'setWelcomeMessage'
what might be the problem in getting empty data? i have wasted a lot of time on this.
Upvotes: 1
Views: 164
Reputation: 158
Thank you for you response. I found answer for my problem.
The reason is that the mongoose has created a model with the plural name. Which means, here i have named the model "account". But here in database it will create/connect to a collection with the name "accounts". I dont know the reason for mongoose not creating/connecting to a collection named "accounts". Since there is no collection named with "accounts" it is always giving me the empty result.
At last, i have changed the collection name to "accounts". Now it working fine.
Please comment the reason, mongoose creating/connecting to plural name of the given model.
Upvotes: 0
Reputation: 89
//getting from postman .... give the account id in postman
query = {account_id:req.body.acnt_id};
//there is match in DB--- getting the data
Account.find(query,function(err,account_data){
if(err){
res.send(err)
}
u wana update
else{
Accoun.update({account_id:req.body.acnt_id},req.body
};
//on body what you enter in postman that will update and store on DB
IN MY KNOWLEDGE
// just example
Model.update
Updates all documents matching conditions using the update clause. All update values are casted to their appropriate types before being sent.
var conditions = { name: 'bourne' }
, update = { $inc: { visits: 1 }}
, options = { multi: true };
Model.update(conditions, update, options, callback);
function callback (err, numAffected) {
// numAffected is the number of updated documents
})
Upvotes: -1
Reputation: 103475
The culprit is this line
query = {account_id:new ObjectId(req.body.acnt_id)}
where the statement new ObjectId(req.body.acnt_id)
creates a new id (regardless of what you pass in the constructor) thus your query fails as there won't be any match in the db. You don't necessarily need to cast the acnt_id
string to ObjectId
as Mongoose does this for you under the hood, but if need be use
query = {account_id:mongoose.Types.ObjectId(req.body.acnt_id)}
otherwise
query = {account_id:req.body.acnt_id}
will suffice.
A better way to do the update would be to use the findOneAndUpdate
method which does an atomic update of your model and mostly used when you want to update a single document in the db and return it to your application, so you can refactor your controller method to:
exports.setMessage = (req, res) => {
const query = { 'account_id': req.body.acnt_id };
const update = {
'$set': {
'message': req.body.welcomeMessage,
'updated_at': new Date(),
}
};
const options = { 'new': true };
Account.findOneAndUpdate(query, update, options, (err, account_data) => {
if (err){
res.send(err)
}
else {
console.log(account_data); // logs the updated account document
res.send({"Status":"Success"})
}
});
}
Also, you can set timestamps in your schema where mongoose assigns createdAt
and updatedAt
fields to your schema and the type assigned is Date
i.e.
let mySchema = mongoose.Schema({
account_id: ObjectId,
account_key: String,
message: String,
}, { timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' } });
Upvotes: 2
Reputation: 1612
.find() returns an array, not a single element. Therefore i'd recommend using the .findOne() method instead.
Upvotes: 0