deleting route for an array in mongodB using node.js - node.js

var userSchema=new mongoose.Schema({
username:String,
password:String,
email:String,
tasks:[{
task: String
}]
});
This is my database schema.I want to create a delete route for the task to be removed.Can anyone tell me how to do so. Right now I am able to fetch the task id.
Here is link to my c9 project https://ide.c9.io/akspan12/newprojectworkspace

var express = require('express');
var router = express();
//I will take static values you can give dynamic values by using req.body
router.post('/Delete_User_Task',function(req,res){
var UserSchema = require('/path/to/Schema.js');//your schema model path
var username = 'akshansh123'; //assume it is present in db
//If you want to remove all task of this user and set one task as empty string your query and changes will be like below
var query = {
'username' :username
};
var changes = {
$set:{
'tasks':[{
task:''
}]
}
};
//If you completely want to remove json array tasks from user document than your query and changes will be like below
var query = {
'username' :username
};
var changes = {
$unset:{
'tasks':''
}
};
//If you want to remove particular task suppose say sleeping from user document than your query and changes will be like below
var query = {
'username' :username
};
var changes = {
$pull:{
'tasks':{
'task':'sleeping'
}
}
};
//If you want to remove selected tasks suppose say sleeping,walking,drinking from user document than your query and changes will be like below
var query = {
'username' :username
};
var changes = {
$pull:{
'tasks':{
'task':{
$in:['sleeping','walking','drinking']
}
}
}
};
UserSchema.update(query,changes,function(err,Result){
if(!err){
res.send('Successfully Removed tasks');
}else{
res.send('something went wrong');
console.log(err);
}
})
})
Hope this may solve your issue!!!

app.patch("/todo/:id",function(req,res){
User
.findById(req.user.id, function(err, foundUser) {
if(err){
req.flash("error",err.message);
console.log(err);
return res.redirect("back");
} if(!foundUser) {
req.flash("error","User not found");
return res.redirect("back");
} else {
foundUser.update({$pull: {tasks: {_id: req.params.id}}}, function(err) {
if(err) {
req.flash("error",err.message);
console.log(err);
return res.redirect("back");
} else {
req.flash("success","Task removed");
return res.redirect("/todo");
}
});
}
});
});
This is the delete route I used.

Related

Can't access fields of MongoDB document in Node.Js

I'm using mongoose and express on my nodejs project.
Trying to get the data from here
app.get('/offers/:id', (req, res) =>{
//store the id from the url
var id = req.params.id;
//just a placeholder
var data = {title: "title", description:"description"};
//store the returned object in a variable
var oop = offers.findById(id, function (err, user) {
if(err){
return err;
}else{
title = user.title;
description = user.description;
this.obj = {
title:title,
description:description
}
console.log(obj)
return obj;
}
} );
console.log(oop)
res.render('single', {data:data});
});
so my idea is to grab the post id from the url, find it in the database, then display the title and description in the corresponding place on the ejs template, but for some reason I can't access the returned data, and what I get is a long list of objects that belongs to mongodb, without the presence of "title" or "description"
Try this, your code has couple of issues & also you need use .lean() to get raw Js objects rather than mongoDB documents :
app.get('/offers/:id', (req, res) => {
//store the id from the url
var id = req.params.id;
//just a placeholder
var data = { title: "title", description: "description" };
//store the returned object in a variable
offers.findById(id).lean().exec((err, user) => {
if (err) {
console.log(err);
res.send(err)
} else {
data.title = user.title;
data.description = user.description;
this.obj = {
title: title,
description: description
}
console.log(obj);
res.render('single', { data: data });
// (Or) res.render('single', { data: obj });
}
});
});
I just modified your code and added comments (all starting with "***").
app.get('/offers/:id', (req, res) =>{
//store the id from the url
var id = req.params.id;
//just a placeholder
var data = {title: "title", description:"description"};
//store the returned object in a variables
// var oop = ***no need for this, the data you want will be in the user variable.
offers.findById(id, function (err, user) {
if(err){
return err;
}else{
// ***this needs to be changed to...
// title = user.title;
// description = user.description;
// ***that...
data.title = user.title;
data.description = user.description;
// ***what's that for??
// this.obj = {
// title:title,
// description:description
// }
// ***this needs to be inside mongoose's callback
res.render('single', {data:data});
}
});
});

How to check if that data already exist in the database before save

Hey guys I have a question, how to do validations before saving the edited or posted (post or put action ) data in mongoose !?
for Example, if action already exist in the database, the user will receive a some sort of error. I try this but not working :
1-NOT WORK
var mongoose = require("mongoose"),
Schema = mongoose.Schema;
var actionSchema = new Schema({
action: {
type: String,
required: true,
},
});
var data = mongoose.model('Action', actionSchema);
actionSchema.pre('save', function (next) { // Middlware to verify if action already existe
var self = this;
data.find({
action: self.action
}, function (err, actions) {
if (!actions.length) {
next();
} else {
console.log('action exists: ', self.name);
next(new Error("Action exists!"));
}
});
});
module.exports = mongoose.model('Action', actionSchema);
2 --- NOT WORK SECOND METHODE : ------------------------------------
var data = mongoose.model('Action', actionSchema);
actionSchema.pre('save', function (next) {
data.count({
action: this.action
}, function (err, count) {
if (count == 1) {
console.log('action exists: ', this.action);
next(new Error("Action exists!"));
//already exists
} else {
next();
//do the action
}
});
});
3- WORKING ALTERNATIVE -- NODE JS CONTROLLER ----I found this trick (work good) that is to do a check before the update (check)
But I would like to know if there is possibility to do it before my save in my model MONGOOSE !?
// router.put('/actions/:action_id');
Action.findById(req.params.action_id, function (err, upaction) {
if (err) { //no action id in database match with params.action_id
res.send(err);
} else { // find == true
// chek if action name existe
Action.findOne({
'action': req.body.action
})
.exec(function (err, found_action) {
if (err) { // ereur bizare sest produite
next(err);
}
if (found_action) { // name action exist
res.send('name action existe');
}
else { // name action no exist
upaction.action = req.body.action;
upaction.save(function (err, acti) {
if (err) {
res.send('error on save');
}
res.send(upaction); // send a document
});
}
});
}
});
Check whether the data already avaliable and then perform the action you want
var data = mongoose.model('data', actionSchema);
data.count({action: this.action}, function(err, count) {
if(count == 1){
//already exists
}
else{
actionSchema.pre('save', function (next) {
});
}
});
I don't understand why are you doing too many operation to do a single operation. Mongodb provides update function which has ability to check and insert. If you want a document to be inserted only when some condition comes true or false. update can do that in a singly query. Here you go.
Action.update({ action:{ $eq:req.body.action }},{ $setOnInsert: new_action }, { upsert: true }, function(err, res){
if(!err && !!res.upserted){
// no document was found hence inserted
}else if(!err && !res.upserted){
// already existing
}else{
// something wicked happend
}
})
Here you need to pay attention that new_action must not be a instance of your mongoose model rather it should be simple object/document which you want to insert.

Mongodb schema defining

Coding a news/media website, I want a "News" section, "Reviews" section, a
"Trending" section, which combines both the previous sections, just like here:
I have made one schema for "News", one for "Reviews".How can I make a "Trending" section(as in the image above "Movies" section)?
Code :
In app.js,
//LANDING PAGE
app.get('/', function (req, res,next) {
Blogdemo.find({}).sort([['_id', -1]]).limit(3).exec(function(err,allBlogs) { //finds latest posts for 1st Schema (upto 3)
if(err) {
console.log(err);
next();
} else {
res.locals.blog = allBlogs;
// res.render("landing", {blog : allBlogs , moment : now});
next();
}
})
}, function (req, res) {
Review.find({}).sort([['_id', -1]]).limit(3).exec(function(err,allReviews) { //finds latest posts of 2nd Schema
if(err) {
console.log(err);
} else {
res.locals.review = allReviews;
res.render("landing", res.locals);
}
})
})
In review.js ,
var mongoose = require("mongoose");
//SCHEMA SETUP
var reviewSchema = new mongoose.Schema({
image : String,
title : String,
body : String,
rating : String,
created : {type : Date, default : Date.now()},
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment" //name of the model
}
]
})
module.exports = mongoose.model("review", reviewSchema);
The "News" schema is almost the same(no review).
Is my way of defining schema wrong? If not, then how can I build the "Trending" section?
Is there any mongodb method which can find the latest posts from "News" and "Reviews" to build the "Trending" section(just like in 1st picture)?
From what i can see from your code, your current News and Review Schema looks fine.
You need to define another Schema for Trending.
var TrendingSchema = new mongoose.Schema({
referenceId : {
type : mongoose.Schema.Types.ObjectId
},
postType : String //To store News or Reviews
});
While saving new News or Reviews, insert the _id of newly saved document in the trending collection.
var news = new News();
news.image = newsImage;
...
news.save(function(err,result)
{
if(!err)
{
var trending = new Trending();
trending.referenceId = result._id;
trending.postType = "News";
treding.save(function(err)
{
if(!err)
{
//success response
}
else
{
//error response
}
});
}
else
{
//send error response
}
});
Similarly while saving Review Post
var review = new Review();
review.image = reviewImage;
...
review.save(function(err,result)
{
if(!err)
{
var trending = new Trending();
trending.referenceId = result._id;
trending.postType = "review"
treding.save(function(err)
{
if(!err)
{
//success response
}
else
{
//error response
}
});
}
else
{
//send error response
}
});
Thus now Trending Collection will contain, newly saved News or Review, in the order they are created. Thus you will be able to get new Review or News Post.
While fetching Trending, you can populate them using News or Review Schema based on the postType.
Trendign.find({}).limit(10).exec(function(err,result)
{
if(!err && result.length!=0)
{
var trendingPosts = [];
result.forEach(function(trending){
if(trending.postType === "News"){
trending.populate({path : 'referenceId',model : 'News'},function(err,populatedItem)
{
if(!err)
{
trendingPosts.push(populatedItem);
}
});
}
else if(trending.postType === "Review"){
trending.populate({path : 'referenceId',model : 'Review'},function(err,populatedItem)
{
if(!err)
{
trendingPosts.push(populatedItem);
}
});
}
});
//now send the trendingPost array with latest News and Review Posts
}
else
{
//send Error response
}
});
Now you can show the latest News or Review and write the type postType.
Hope this is what you want.

Return partial documents from Node API querying Mongo

I have a Node API that is querying my Mongo database.
I'm able to return all documents within a collection. Now, I want to return partial documents.
My model (i.e. Player.js) looks like this:
var mongoose = require('mongoose');
// Create schema for players
var playerSchema = mongoose.Schema(
{
player_name:String,
goals:Number,
clubs:
{
club_name:String,
season:String
}
}
);
var Player = module.exports = mongoose.model('Player',playerSchema);
// get all players
module.exports.getPlayers = function(callback, limit){
Player.find(callback).limit(limit);
};
My application looks like this:
//...
app.get('/api/players',function(req,res){
Player.getPlayers(function(err,players){
if(err){
throw err;
}
res.json(players);
});
});
//...
I'd like to query all documents within my players collection but return only player_name when I go to ".../api/players/player_names"
I thought adding the code below would work but it doesn't...
This on my model:
// [previous code]
// get all player names
module.exports.getPlayerNames = function(callback,limit){
Player.find(callback,player_name:1).limit(limit)
}
This on my app.js:
//...
app.get('api/players/player_names',function(req,res){
Player.getPlayerNames(function(err,players){
if(err){
throw err;
}
res.json(players);
});
});
//...
You'll probably want something that looks like this:
var mongoose = require('mongoose');
// Create schema for players
var playerSchema = mongoose.Schema(
{
player_name:String,
goals:Number,
clubs:
{
club_name:String,
season:String
}
}
);
//Its most common to pass the callback last, as this is what others do
playerSchema.statics.getPlayers = function(limit, callback){
this.find({})
.select('player_name')
.limit(limit)
.exec(callback);
};
module.exports = mongoose.model('Player',playerSchema);
Which will return results like [{_id: ObjectId, player_name: "player1"}, ...].
If you want to return just an array of player names:
var mongoose = require('mongoose');
// Create schema for players
var playerSchema = mongoose.Schema(
{
player_name:String,
goals:Number,
clubs:
{
club_name:String,
season:String
}
}
);
//Its most common to pass the callback last, as this is what others do
playerSchema.statics.getPlayers = function(limit, callback){
this.find({})
.select('player_name')
.limit(limit)
.exec(function(err, docs) {
if(err) return callback(err); //first argument should be reserved for passing any errors
callback(null, docs.map(function(doc) {
return doc.player_name;
});
});
};
module.exports = mongoose.model('Player',playerSchema);

Mongoose update query not working with node.js

First I am making entries in mongodb by:
var device = new Device(inputDetailsJson); //device model instance
device.save(function(err) {
if (err) {
res.send(err);
} else {
res.write('Successful');
res.end();
}
});
This is the device model:
// Dependencies
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// Schema Definition
var deviceSchema=new Schema ({
"deviceId":{ type : String , unique: true},
"version":{ type : String },
"manufacturer":{ type : String },
"modelname":{ type : String },
});
// Model
module.exports = mongoose.model('de', deviceSchema);
This is the inputDetailsJson:
{
"deviceId":"3236172417",
"version":"5.2.3",
"manufacturer":"abc",
"modelname":"example"
}
These details are getting entered correctly, but when I try to update something, it reflects no changes.
var device=new Device();
device.update({deviceId:"3236172417"},{modelname:"test"}
,function(err) {
if (err) {
return console.error(err);
}
else{
res.write('successful');
res.end();
It displays 'successful' even though no changes are made in the mongodb database.
var Device = require('your device model file');
Device.model.findOneAndUpdate({
deviceId:"3236172417",
},{$set:{modelname:"test}},function(err, user) {
});
For updating the device you don't need to create a new device, using var device=new Device();
you should simply update, same as you try to find a document.
Device.update({deviceId:"3236172417"},{modelname:"test"}
,function(err) {
if (err) {
return console.error(err);
}
else{
res.write('successful');
res.end();

Resources