MEAN Stack - Update route not posting correctly - node.js

I have built a mean app but am having an issue with it posting a number value. I'm not sure if it is a mongoose validation error but for some reason mongoose can not upsert the number value but will when it is a string.
Here's the route:
//Edit A Site
router.put('/api/sites/:site_id', function(req, res) {
Site.findById(req.params.site_id, function(err, site) {
if (err) {
res.send(err);
} else {
if(req.body.ip) site.ip = req.body.ip;
if(req.body.domain) site.domain = req.body.domain;
if(req.body.wp) site.wp = req.body.wp;
if(req.body.host_name) site.host_name = req.body.host_name;
if(req.body.hosted) site.hosted = req.body.hosted;
console.log(req.body);
// save the site
site.save(function(err) {
if (err)
res.send(err);
res.json(site);
});
}
});
});
The console.log has the full request body:
{ hosted: 1, host_name: 'sup', wp: 'n/a' }
But this is the mongoose response: Mongoose: sites.update({ _id: ObjectId("57a16c4a7f7e5b7a7e1f5ad1") }, { '$set': { host_name: 'sup', wp: 'n/a' } })
Schema:
// grab the things we need
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// create a schema
var sitesEntrySchema = new Schema({
ip: {
type: String,
required: true,
trim: true
},
domain: {
type: String,
required: true,
trim: true
},
wp: {
type: String,
required: true,
trim: true
},
host_name: {
type: String,
required: true
},
hosted: {
type: Number,
min: 0,
max: 1,
required: true
}
});
// make this available to our users in our Node applications
var Site = mongoose.model('Site', sitesEntrySchema);
module.exports = Site;
EDIT:
I believe I found the solution. When checking for the req.body.hosted, because it is a number it fails. I had to update to check for undefined:
if(req.body.hosted != undefined) site.hosted = req.body.hosted;

Related

How to disable/inactive the data in mongoDB database instead of delete using nodejs

when I hit the delete method in postman I need to disable the data in MongoDB instead of completely delete. how to do that?
router.delete("/admin/delete_profile/:id", async (req, res) => {
try {
await SomeModel.findByIdAndDelete(req.params.id.trim());
return send(res, RESPONSE.SUCCESS);
} catch (err) {
// res.status(404).send(err.message);
return send(res, RESPONSE.UNKNOWN_ERROR);
}
});
schema.js
const { json } = require("body-parser");
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const SomeModelSchema = new Schema({
first_name: {
type: String,
required: true,
},
last_name: {
type: String,
required: true,
},
image: {
data: Buffer,
type: String,
required: true,
},
});
module.exports = mongoose.model("SomeModel", SomeModelSchema);
Actually, the approach suggested by #PawanYadav is a good one in my opinion.
Declare a Boolean flag isActive in your Schema (default to true):
const SomeModelSchema = new Schema({
first_name: {
type: String,
required: true,
},
last_name: {
type: String,
required: true,
},
image: {
data: Buffer,
type: String,
required: true,
},
isActive: {
type: Boolean,
default: true,
}
});
And use findByIdAndUpdate to set the flag to false to disable the data:
try {
await SomeModel.findByIdAndUpdate(req.params.id.trim(), {
isActive: false,
});
return send(res, RESPONSE.SUCCESS);
} catch (err) {
// res.status(404).send(err.message);
return send(res, RESPONSE.UNKNOWN_ERROR);
}
You can keep a key like isActive:true in your database for soft delete purpose.When you hit delete api you can simply change this key to false.In this way you can differentiate this document from others and when you want list you can check for documents with isActive:true in your query.

Mongoose findOneAndUpdate won't update my database

I am teaching myself NodeJS while working on an app. I use Mongoose and Axios.
On one section of the app I display the partners and when I click on update I get a form with the informations of the selected partner in order to update them.
The client-side sends in the infos to the server but the server won't update the entries in the database. Here is my server side
app.post("/api/partner/update", (req, res) => {
const id = req.body.id;
const fullname = req.body.fullname;
const email = req.body.email;
const phones = req.body.phones;
const shops = req.body.shops;
const company = req.body.company;
console.log("The body is ",req.body) //It returns the correct data from the client's side submited data
Partner.findOneAndUpdate(id, mongoose.set('useFindAndModify', false),
{
"fullname": fullname,
"email": email,
"phones": phones,
"shops":shops,
"company": company
},
(err, document) => {
if (err) return err;
//console.log(document);
res.send({ document });
}
);});
Here is my model :
const mongoose = require("mongoose");
const partnerSchema = mongoose.Schema(
{
fullname: {
type: String,
maxlength: 50,
required: true
},
email: {
type: String,
trim: true,
unique: 1,
required: true
},
phones: {
type: Array
},
company: {
type: String,
maxlength: 50,
required: true
},
shops: {
type: Array,
default: 0
},
is_valid: {
type: Boolean
},
validated_by: {
type: String
},
created_by: {
type: String,
maxlength: 50
},
updated_by: {
type: String
},
deleted_by: {
type: String
},
deleted_at: {
type: Date,
default: null
}
},
{
timestamps: {
createdAt: "created_at",
updatedAt: "updated_at"
}
}
);
const Partner = mongoose.model("Partner", partnerSchema)
module.exports ={Partner}
I don't understand why it is not updating the fields in the dataBase
This is a syntax for findOneAndUpdate as per the docs:
var query = { name: 'borne' };
Model.findOneAndUpdate(query, { name: 'jason bourne' }, options, callback)
Change db query to this:
let query = {_id: id };
let dataToUpdate= {
"fullname": fullname,
"email": email,
"phones": phones,
"shops":shops,
"company": company
}
let options = {useFindAndModify: false} // useFindAndModify set to false at query level
// options = {useFindAndModify: false,new:true} if you want updated docs in return
Partner.findOneAndUpdate(query,dataToUpdate,options,(err, document) => {
if (err) return err;
//console.log(document);
res.send({ document });
}
)
To set Deprecation Warnings on or off at mongoose level use option
mongoose.set('useFindAndModify', false)
Read more here:
Deprecation Warnings
findOneAndReplace
You can also use findByIdAndUpdate method:
Model.findByIdAndUpdate(id, update, options, callback)
You can enable promises to make code more readable and testable:
https://mongoosejs.com/docs/promises.html
Refering the doc, https://mongoosejs.com/docs/tutorials/findoneandupdate.html
first parameter of findOneAndUpdate should be a filter object, not the id directly.
So please try Partner.findOneAndUpdate({'_id': id},....

How to use mongoose to make changes in two different collections in one nodejs query

In this application, I am trying to update a field value, if it is successful then I want to save into a log collection, however, not all the data are saved in the log collection, I am not sure if I am doing it the right way, would appreciate if someone could help out.
here is the query :
// both models(Log & Inventory are imported)
router.get("/add_product/:id/:num/:quantity/:order", (req, res) => {
var id = req.params.id;
var quantity = req.params.quantity;
var order = req.params.order;
// console.log('id----', id);
var num_mod = req.params.num;
var modified_count = parseInt(num_mod) - parseInt(quantity);
console.log("num_mod----", num_mod);
Inventory.findByIdAndUpdate(id, { quantity: parseInt(num_mod) }, { new: true }, function(
err,
inventory
) {
if (err) {
console.log("err", err);
res.status(500).send(err);
} else {
console.log(inventory.name);
const newLog = new Log({
name: inventory.name,
description: inventory.description,
price: parseInt(inventory.price),
quantity: parseInt(inventory.quantity),
modified_quantity: parseInt(modified_count),
itemDest: order //this is not being saved
});
newLog.save(function(err, Log) {
if (err) {
console.log(err);
} else {
console.log("add log success");
res.send(inventory);
}
});
}
});
});
URL from front end :
// order is a string
here is the Log schema :
const mongoose = require("mongoose");
const LogSchema = new mongoose.Schema(
{
// _id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
quantity: { type: Number, required: true },
modified_quantity: { type: Number, required: true },
supplier: String,
taxable: Boolean,
itemDest: String
},
{ timestamps: true }
);
// Create model from the schema
const Log = mongoose.model("Log", LogSchema);
// Export model
module.exports = Log;
and here is the inventory schema
const mongoose = require("mongoose");
//create Schema
const InventorySchema = new mongoose.Schema(
{
// _id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
quantity: { type: Number, required: true },
supplier: String,
taxable: Boolean
},
{ timestamps: true }
);
// Create model from the schema
const Inventory = mongoose.model("Inventory", InventorySchema);
// Export model
module.exports = Inventory;
My issue is with this line "itemDest: order" in the query, I intend to save the value of "order" extracted from "req.params.order" into "itemDest" but it doesn't save.

Prevent server from crashing while interacting with db

I'm trying to create login form using mongoose. The error has been occurred when I try to find for example an email in my database an it doesn't exist. In this case my app crashed.
Here is my UserSchema:
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
credit:{
type: Number,
default:0
},
email: {
type: String,
unique: true,
required: true,
trim: true
},
telegramId:{
type: String,
trim: true,
required: true
},
password: {
type: String,
required: true
},
inboxMessages: {
type: Array
},
submittedBooks:{
type: Array
},
profilePicture: {
type: String,
default: '/'
}
});
var User = mongoose.model('User', userSchema);
module.exports = User;
and this is my NodeJS code and query:
UserModel.find({name: 'akbar'}, (err, data) =>{
if (err) {
console.log(err);
}
else{
console.log(data[0].password);
}
})
UserModel.find({name: 'akbar'}, ....) cause an error which contains TypeError: Cannot read property 'password' of undefined. How can I prevent crashing my app?
When you try to find an object from the database, there might be 3 scenarios.
Internal server error (You checked this).
Empty or null value. (You have not checked it yet).
Got the desired object. (You print these values)
So to checked scenario 2, use the following code,
UserModel.find({name: 'akbar'}, (err, data) =>{
if (err) {
console.log(err);
} else if ((!data) || (data.length <= 0)) {
console.log('No objecct exist');
} else{
console.log(data[0].password);
}
})
In your NodeJS did you import as
var userModel = require('place_you_defined_the_model')
else, if its just import, like import('place_you_define_model')then you should use,
user.find({name:'Akbar'})

mongoose modify multi level subdocument then save not work normally

I have a Torrent item, it has subdocument array named '_replies' to saved user comments, and every comment also include subdocument array '_replies' to saved user reply, this is my all schema define:
var CommentSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'User'
},
comment: {
type: String,
default: '',
trim: true
},
_replies: [this],
createdat: {
type: Date,
default: Date.now
},
editedby: {
type: String,
default: '',
trim: true
},
editedat: {
type: Date,
default: ''
}
});
var TorrentSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'User'
},
torrent_filename: {
type: String,
default: '',
trim: true,
required: 'filename cannot be blank'
},
torrent_title: {
type: String,
default: '',
trim: true,
required: 'title cannot be blank'
},
_replies: [CommentSchema]
});
mongoose.model('Torrent', TorrentSchema);
mongoose.model('Comment', CommentSchema);
the first level comment of torrent update/delete fine, the code of server controller likes below:
exports.update = function (req, res) {
var torrent = req.torrent;
torrent._replies.forEach(function (r) {
if (r._id.equals(req.params.commentId)) {
r.comment = req.body.comment;
r.editedat = Date.now();
r.editedby = req.user.displayName;
torrent.save(function (err) {
if (err) {
return res.status(422).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(torrent); //return data is Correct, and save to mongo is Correct
}
});
}
});
};
but when i used Alike function to update/delete _replies._replies, it can return Correct json of torrent to response, Unfortunate, the save to mongo not fine, the code:
exports.SubUpdate = function (req, res) {
var torrent = req.torrent;
torrent._replies.forEach(function (r) {
if (r._id.equals(req.params.commentId)) {
r._replies.forEach(function (s) {
if (s._id.equals(req.params.subCommentId)) {
s.comment = req.body.comment;
s.editedat = Date.now();
s.editedby = req.user.displayName;
torrent.save(function (err) {
if (err) {
return res.status(422).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(torrent);//return data is Correct, but save to mongo is incorrect
}
});
}
});
}
});
};
also, i can delete first level comment, but can not delete second level comment reply, all the json data of torrent is correct, only not save to mongo.
what can i do more?
I already solve it, i add this code before .save().
torrent.markModified('_replies');
it work fine!

Resources