I know how to...
Remove a single document.
Remove the collection itself.
Remove all documents from the collection with Mongo.
But I don't know how to remove all documents from the collection with Mongoose. I want to do this when the user clicks a button. I assume that I need to send an AJAX request to some endpoint and have the endpoint do the removal, but I don't know how to handle the removal at the endpoint.
In my example, I have a Datetime collection, and I want to remove all of the documents when the user clicks a button.
api/datetime/index.js
'use strict';
var express = require('express');
var controller = require('./datetime.controller');
var router = express.Router();
router.get('/', controller.index);
router.get('/:id', controller.show);
router.post('/', controller.create);
router.put('/:id', controller.update);
router.patch('/:id', controller.update);
router.delete('/:id', controller.destroy);
module.exports = router;
api/datetime/datetime.controller.js
'use strict';
var _ = require('lodash');
var Datetime = require('./datetime.model');
// Get list of datetimes
exports.index = function(req, res) {
Datetime.find(function (err, datetimes) {
if(err) { return handleError(res, err); }
return res.json(200, datetimes);
});
};
// Get a single datetime
exports.show = function(req, res) {
Datetime.findById(req.params.id, function (err, datetime) {
if(err) { return handleError(res, err); }
if(!datetime) { return res.send(404); }
return res.json(datetime);
});
};
// Creates a new datetime in the DB.
exports.create = function(req, res) {
Datetime.create(req.body, function(err, datetime) {
if(err) { return handleError(res, err); }
return res.json(201, datetime);
});
};
// Updates an existing datetime in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Datetime.findById(req.params.id, function (err, datetime) {
if (err) { return handleError(res, err); }
if(!datetime) { return res.send(404); }
var updated = _.merge(datetime, req.body);
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, datetime);
});
});
};
// Deletes a datetime from the DB.
exports.destroy = function(req, res) {
Datetime.findById(req.params.id, function (err, datetime) {
if(err) { return handleError(res, err); }
if(!datetime) { return res.send(404); }
datetime.remove(function(err) {
if(err) { return handleError(res, err); }
return res.send(204);
});
});
};
function handleError(res, err) {
return res.send(500, err);
}
DateTime.remove({}, callback) The empty object will match all of them.
.remove() is deprecated. instead we can use deleteMany
DateTime.deleteMany({}, callback).
In MongoDB, the db.collection.remove() method removes documents from a collection. You can remove all documents from a collection, remove all documents that match a condition, or limit the operation to remove just a single document.
Source: Mongodb.
If you are using mongo sheel, just do:
db.Datetime.remove({})
In your case, you need:
You didn't show me the delete button, so this button is just an example:
<a class="button__delete"></a>
Change the controller to:
exports.destroy = function(req, res, next) {
Datetime.remove({}, function(err) {
if (err) {
console.log(err)
} else {
res.end('success');
}
}
);
};
Insert this ajax delete method in your client js file:
$(document).ready(function(){
$('.button__delete').click(function() {
var dataId = $(this).attr('data-id');
if (confirm("are u sure?")) {
$.ajax({
type: 'DELETE',
url: '/',
success: function(response) {
if (response == 'error') {
console.log('Err!');
}
else {
alert('Success');
location.reload();
}
}
});
} else {
alert('Canceled!');
}
});
});
MongoDB shell version v4.2.6
Node v14.2.0
Assuming you have a Tour Model: tourModel.js
const mongoose = require('mongoose');
const tourSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'A tour must have a name'],
unique: true,
trim: true,
},
createdAt: {
type: Date,
default: Date.now(),
},
});
const Tour = mongoose.model('Tour', tourSchema);
module.exports = Tour;
Now you want to delete all tours at once from your MongoDB, I also providing connection code to connect with the remote cluster.
I used deleteMany(), if you do not pass any args to deleteMany(), then it will delete all the documents in Tour collection.
const mongoose = require('mongoose');
const Tour = require('./../../models/tourModel');
const conStr = 'mongodb+srv://lord:<PASSWORD>#cluster0-eeev8.mongodb.net/tour-guide?retryWrites=true&w=majority';
const DB = conStr.replace('<PASSWORD>','ADUSsaZEKESKZX');
mongoose.connect(DB, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
})
.then((con) => {
console.log(`DB connection successful ${con.path}`);
});
const deleteAllData = async () => {
try {
await Tour.deleteMany();
console.log('All Data successfully deleted');
} catch (err) {
console.log(err);
}
};
Your_Mongoose_Model.deleteMany({}) can do the job
References:
https://mongoosejs.com/docs/api.html#query_Query-deleteMany
https://www.geeksforgeeks.org/mongoose-deletemany-function/
Related
My problem is that I can enter data from my input boxes into an SQL table, but the problem is that the text from the table will not show on the page i want to. What works is that the playlist page will show the a href links depending on how many playlists i have made just not the text.
I have left out the database details for security reasons.
playlist.jade
extends layout
block content
h1= title
p Welcome to #{title}
h1 My Playlists
br
a(href='/login') Login
br
a(href='/users/createPlaylist') Create a new Playlists
br
a(href='/users/playlistCreated') test
br
for playlist, i in playlists
a(href='/users/playlistCreated') | #{playlist.text}
br
users.js
var express = require('express');
var mysql = require('mysql');
var router = express.Router();
var dbConnectionInfo = {
host : '',
user : '',
password : '',
database : 'audio_collections'
};
router.get('/createPlaylist', function(req, res, next) {
res.render('new_playlist');
});
router.get('/playlistCreated', function(req, res, next) {
res.render('name_of_created_playlist');
});
router.get('/songCreated', function(req, res, next) {
res.render('song_page');
});
router.get('/newSong', function(req, res, next) {
res.render('new_song');
});
router.post('/newPlaylist', function(req, res, next) {
var dbConnection = mysql.createConnection(dbConnectionInfo);
dbConnection.connect();
dbConnection.on('error', function(err) {
if (err.code == 'PROTOCOL_SEQUENCE_TIMEOUT') {
// Let's just ignore this
console.log('Got a DB PROTOCOL_SEQUENCE_TIMEOUT Error ... ignoring ');
} else {
// I really should do something better here
console.log('Got a DB Error: ', err);
}
});
var playlist = {
text: req.body.thePlaylist
};
dbConnection.query('INSERT INTO Playlists (playlist_name) VALUES(?)', [playlist.text], function(err, results, fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
if (err) {
throw err;
}
// notice that results.insertId will give you the value of the AI (auto-increment) field
playlist.id = results.insertId;
// Going to convert my joke object to a JSON string a print it out to the console
console.log(JSON.stringify(playlist));
// Close the connection and make sure you do it BEFORE you redirect
dbConnection.end();
res.redirect('/');
});
router.post('/newSongAdded', function(req, res, next) {
var dbConnection = mysql.createConnection(dbConnectionInfo);
dbConnection.connect();
dbConnection.on('error', function(err) {
if (err.code == 'PROTOCOL_SEQUENCE_TIMEOUT') {
// Let's just ignore this
console.log('Got a DB PROTOCOL_SEQUENCE_TIMEOUT Error ... ignoring ');
} else {
// I really should do something better here
console.log('Got a DB Error: ', err);
}
});
var song = {
text: req.body.theSong,
url: req.body.theSongURL
};
dbConnection.query('INSERT INTO Songs (song_name, song_url) VALUES(?,?)',[song.text, song.url], function(err, results,fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
if (err) {
throw err;
}
// notice that results.insertId will give you the value of the AI (auto-increment) field
song.id = results.insertId;
// Going to convert my joke object to a JSON string a print it out to the console
console.log(JSON.stringify(song));
// Close the connection and make sure you do it BEFORE you redirect
dbConnection.end();
res.redirect('/');
});
});
});
module.exports = router;
index.js
var express = require('express');
var mysql = require('mysql');
var router = express.Router();
var dbConnectionInfo = {
host : '',
user : '',
password : '',
database : 'audio_collections'
};
/* GET home page. */
router.get('/login', function(req, res, next) {
res.render('login');
});
router.post('/login', function(req, res, next) {
var username = req.body.username;
username = username.trim();
if (username.length == 0) {
res.redirect('/login');
}
else {
req.session.username = username;
res.redirect('/');
}
});
router.get('/', function(req, res, next) {
var dbConnection = mysql.createConnection(dbConnectionInfo);
dbConnection.connect();
dbConnection.on('error', function(err) {
if (err.code == 'PROTOCOL_SEQUENCE_TIMEOUT') {
// Let's just ignore this
console.log('Got a DB PROTOCOL_SEQUENCE_TIMEOUT Error ... ignoring ');
} else {
// I really should do something better here
console.log('Got a DB Error: ', err);
}
});
dbConnection.query('SELECT * FROM Playlists', function(err, results, fields){
if (err) {
throw err;
}
var allPlaylists = new Array();
for (var i = 0; i < results.length; i++) {
var playlist = {
id: results[i].id,
text: results[i].text
};
console.log(JSON.stringify(playlist));
allPlaylists.push(playlist);
}
dbConnection.end();
res.render('playlists', {playlists: allPlaylists});
});
router.get('/users/playlistCreated', function(req, res, next) {
var dbConnection = mysql.createConnection(dbConnectionInfo);
dbConnection.connect();
dbConnection.on('error', function(err) {
if (err.code == 'PROTOCOL_SEQUENCE_TIMEOUT') {
// Let's just ignore this
console.log('Got a DB PROTOCOL_SEQUENCE_TIMEOUT Error ... ignoring ');
} else {
// I really should do something better here
console.log('Got a DB Error: ', err);
}
});
dbConnection.query('SELECT * FROM Songs', function(err, results, fields){
if (err) {
throw err;
}
var allSongs = new Array();
for (var i = 0; i < results.length; i++) {
var song = {};
song.id = results[i].id;
song.text = results[i].text;
song.url = results[i].url;
console.log(JSON.stringify(song));
allSongs.push(song);
}
dbConnection.end();
res.render('name_of_created_playlist', {songs: allSongs});
});
});
});
module.exports = router;
new_playlist.jade
extends layout
block content
form(method='POST', action='/users/newPlaylist')
div
label(for='thePlaylist') Name of Playlist
div
textarea(type='text', name='thePlaylist')
br
input(type='submit', name='Add new Playlist')
a(href='/') Cancel
Here is the database and table setups
database and table setup
I would really appreciate the help and I have been stuck on this for a week now.
Got it fixed I didnt need the for loops inside my array
Only needed var allPlaylist = results; Since results is an array already
How can I add a new document and return the whole collection? For example, I want to add a message and the respose should have all messages added
create: function(req, res) {
var user_id = req.token.sid;
req.allParams().user = user_id;
Message.create(req.allParams(), function(err, message) {
if (err) return res.json(err.status, {err: err});
});
});
You can create a custom route for your action in config/routes.js:
'POST message/create' : { controller: 'MessageController', action: 'create' }
And add some lines to your code in the MessageController.js:
create: function(req, res) {
var user_id = req.token.sid;
req.allParams().user = user_id;
Message.create(req.allParams(), function(err, message) {
if (err) return res.json(err.status, {err: err});
Message.find().exec(function(err, messages){
if (err) return res.json(err.status, {err: err});
return res.json(messages);
})
});
}
it works for me.
I have been doing an example based on the TV showTracker and So far I couldn't get any shows into my website. I have been trying so hard to whether I have made a mistake but I still couldn't find anything. So How to I retrieve these information. I have stared this server.js and mongod in separate CMDs and gulp in another CMD I still couldn't get any of the shows. When I see the responses it will show a blank array "[]" like this. So any advice? Help would be most appreciated. (I have host the website yet, thought this would help also to my question). The error in the net debugger says api/shows/ - response = [ ]
Here is my server.jsrespone
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var showSchema = new mongoose.Schema({
_id: Number,
name: String,
airsDayOfWeek: String,
airsTime: String,
firstAired: Date,
genre: [String],
network: String,
overview: String,
rating: Number,
ratingCount: Number,
status: String,
poster: String,
subscribers: [{
type: mongoose.Schema.Types.ObjectId, ref: 'User'
}],
episodes: [{
season: Number,
episodeNumber: Number,
episodeName: String,
firstAired: Date,
overview: String
}]
});
var userSchema = new mongoose.Schema(
{
email: { type: String, unique: true },
password: String
});
userSchema.pre('save', function (next) {
var user = this;
if (!user.isModified('password')) return next();
bcrypt.genSalt(10, function (err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
});
userSchema.methods.comparePassword = function (candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
}
var User = mongoose.model('User', userSchema);
var Show = mongoose.model('Show', showSchema);
mongoose.connect('localhost');
var app = express();
app.set('port', process.env.PORT || 3000);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({ secret: 'keyboard cat' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(path.join(__dirname, 'public')));
app.listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
app.get('/api/shows', function (req, res, next) {
var query = Show.find();
if (req.query.genre) {
query.where({ genre: req.query.genre });
} else if (req.query.alphabet) {
query.where({ name: new RegExp('^' + '[' + req.query.alphabet + ']', 'i') });
} else {
query.limit(12);
}
query.exec(function (err, shows) {
if (err) return next(err);
res.send(shows);
});
});
app.get('/api/shows/:id', function (req, res, next) {
Show.findById(req.params.id, function (err, show) {
if (err) return next(err);
res.send(show);
});
});
app.post('/api/shows', function (req, res, next) {
var apiKey = 'E36B52F7E036AFF3';
var seriesName = req.body.showName
.toLowerCase()
.replace(/ /g, '_')
.replace(/[^\w-]+/g, '');
var parser = xml2js.Parser({
explicitArray: false,
normalizeTags: true
});
async.waterfall([
function (callback) {
request.get('http://thetvdb.com/api/GetSeries.php?seriesname=' + seriesName, function (error, response, body) {
if (error) return next(error);
parser.parseString(body, function (err, result) {
if (!result.data.series) {
return res.send(404, { message: req.body.showName + ' was not found.' });
}
var seriesId = result.data.series.seriesid || result.data.series[0].seriesid;
callback(err, seriesId);
});
});
},
function (seriesId, callback) {
request.get('http://thetvdb.com/api' + apiKey + '/series/' + seriesId + '/all/en.xml', function (error, response, body) {
if (error) return next(error);
parser.parseString(body, function (err, result) {
var series = result.data.series;
var episodes = result.data.episode;
var show = new Show({
_id: series.id,
name: series.seriesname,
airsDayOfWeek: series.airs_dayofweek,
airsTime: series.airs_time,
firstAired: series.firstaired,
genre: series.genre.split('|').filter(Boolean),
network: series.network,
overview: series.overview,
rating: series.rating,
ratingCount: series.ratingcount,
runtime: series.runtime,
status: series.status,
poster: series.poster,
episodes: []
});
_.each(episodes, function (episode) {
show.episodes.push({
season: episode.seasonnumber,
episodeNumber: episode.episodenumber,
episodeName: episode.episodename,
firstAired: episode.firstaired,
overview: episode.overview
});
});
callback(err, show);
});
});
},
function (show, callback) {
var url = 'http://thetvdb.com/banners/' + show.poster;
request({ url: url, encoding: null }, function (error, response, body) {
show.poster = 'data:' + response.headers['content-type'] + ';base64,' + body.toString('base64');
callback(error, show);
});
}
], function (err, show) {
if (err) return next(err);
show.save(function (err) {
if (err) {
if (err.code == 11000) {
return res.send(409, { message: show.name + ' already exists.' });
}
return next(err);
}
res.send(200);
});
});
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) next();
else res.send(401);
};
app.use(function (req, res, next) {
if (req.user) {
res.cookie('user', JSON.stringify(req.user));
}
next();
});
app.get('*', function (req, res) {
res.redirect('/#' + req.originalUrl);
})
app.use(function (err, req, res, next) {
console.error(err.stack);
res.send(500, { message: err.message });
});
Change var query = Show.find(); in /api/shows to
var query = Show.find(function(err, showdata){
// all the checking and the res.send(shows) goes here
})
Just wait for data and do all the operation(asynchronous)
OK Guys, I finally found the answer to the question. It's nothing wrong with the script (server.js). It is because I think it cannot hold the data in the database ('localhost:27017/test'). That is why maybe I'm getting a null response from the TVDB API. Once I changed my database and connect strings to (
'mongodb://nixsiow:abcd1234#ds027479.mongolab.com:27479/nixshowtrackrapp'
, It worked like a charm.
So maybe my answer may not explain this properly, or you can look for more details in stack overflow. Thanks for the help guys. I hope that this will help who try to do this tutorial and get stuck on this step.
So final Answer:
mongoose.connect('mongodb://nixsiow:abcd1234#ds027479.mongolab.com:27479/nixshowtrackrapp');
var agenda = require('agenda')({ db: { address: 'mongodb://nixsiow:abcd1234#ds027479.mongolab.com:27479/nixshowtrackrapp' } });
Also Nixsow's website may have a help, it is the most recent update that I found for this tutorial.
I've just started with meanjs. When I've taken a look at it server side module user profile controller, I find that mongoose model User is available in req object.
From where it has got added in req object?
Refer the code below, I wants to understand var user = req.user;, How user is added in req object?
'use strict';
/**
* Module dependencies.
*/
var _ = require('lodash'),
errorHandler = require('../errors.server.controller.js'),
mongoose = require('mongoose'),
passport = require('passport'),
User = mongoose.model('User');
/**
* Update user details
*/
exports.update = function(req, res) {
// Init Variables
var user = req.user;
var message = null;
// For security measurement we remove the roles from the req.body object
delete req.body.roles;
if (user) {
// Merge existing user
user = _.extend(user, req.body);
user.updated = Date.now();
user.displayName = user.firstName + ' ' + user.lastName;
user.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
res.json(user);
}
});
}
});
} else {
res.status(400).send({
message: 'User is not signed in'
});
}
};
/**
* Send User
*/
exports.me = function(req, res) {
res.json(req.user || null);
};
In meanjs app.param([name], callback) is used, whenever a route with some id like articeId in parameter is accessed, app.param([name], callback) middleware is triggered. In meanjs it sets req.article like this.
app.param('articleId', articles.articleByID);
and in articleByID
exports.articleByID = function(req, res, next, id) {
if (!mongoose.Types.ObjectId.isValid(id)) {
return res.status(400).send({
message: 'Article is invalid'
});
}
Article.findById(id).populate('user', 'displayName').exec(function(err, article) {
if (err) return next(err);
if (!article) {
return res.status(404).send({
message: errorHandler.getErrorMessage(err)
});
}
req.article = article;
next();
});
};
more on app.param see http://expressjs.com/api.html#app.param
Passport’s authentication middleware sets req.user upon successful login.
See http://passportjs.org/guide/authenticate/.
I've been trying to avoid overhead in my routes.js file.
Here's it:
module.exports = function(app, db) {
app.get('/', function(req, res) {
res.render('index')
});
app.get('/contact-us', function(req, res) {
var col = db.collection('contacts');
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'gmail.user#gmail.com',
pass: 'userpass'
}
});
});
});
}
As you can see, this is already becomes flooded by business logic just by instantiating mongo collection and mail transporter. I couldn't find any materials on how to delegate this logic to the outer module, for example, sendmail.js, savetomongo.js etc..
Any suggestions?
Some modification have done by me. I have updated according your requirement.
You need to make it according your actual need.
var sendmail = require('./sendmail.js');
var savetomongo = require('./savetomongo.js');
module.exports = function(app, db) {
app.get('/', function(req, res) {
res.render('index')
});
app.get('/contact-us', function(req, res) {
var col = db.collection('contacts');
var document = {'id': 'xyz'};
savetomongo.save(col, document, function(error, is_save) {
if (error) {
//handle error
} else {
// next()
sendmail.sendEmail('DUMMY <from#xyz.com>', 'to#xyz.com', 'TestEmail', 'Only for testing purpose', function(error, isSend) {
if (error) {
//handle error
} else {
// next()
//res.render('index')
}
});
}
});
});
}
//sendmail.js
module.exports = {
sendEmail: function(fromEmailFormatted, toEmail, subject, message, fn) {
var mailOptions = {
from: fromEmailFormatted, // sender address
to: toEmail, // list of receivers
subject: subject, // Subject line
html: message // html body
};
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'gmail.user#gmail.com',
pass: 'userpass'
}
});
// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
return fn(error);
} else {
return fn(null, true);
}
});
}
}
//savetomongo.js
module.exports = {
save: function(col, data, fn) {
col.insert(data, {w: 1}, function(err, records) {
if (err) {
return fn(err);
} else {
return fn(null, records);
}
});
}
}