I'm working on creating a CRUD todo app using AngularJS, Node, Express, and MongoDB. I've got all parts figured out except for update part. I'm not really sure how to implement that or what the code might look like. Particularly the AngularJS stuff (express routing isn't so bad). I'd like it if I could update by ID. Was hoping to get some input.
function mainController($scope, $http) {
$scope.formData = {};
// when landing on the page, get all todos and show them
$http.get('/api/todos')
.success(function(data) {
$scope.todos = data;
})
.error(function(data) {
console.log('Error: ' + data);
});
// when submitting the add form, send the text to the node API
$scope.createTodo = function() {
$http.post('/api/todos', $scope.formData)
.success(function(data) {
$('input').val('');
$scope.todos = data;
})
.error(function(data) {
console.log('Error: ' + data);
});
};
// delete a todo after checking it
$scope.deleteTodo = function(id) {
$http.delete('/api/todos/' + id)
.success(function(data) {
$scope.todos = data;
})
.error(function(data) {
console.log('Error: ' + data);
});
};
Here are the routes just in case that matters.
app.get('/api/todos', function(req, res) {
// use mongoose to get all todos in the database
Todo.find(function(err, todos) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err)
res.send(err)
res.json(todos); // return all todos in JSON format
});
});
// create todo and send back all todos after creation
app.post('/api/todos', function(req, res) {
// create a todo, information comes from AJAX request from Angular
Todo.create({
text : req.body.text,
done : false
}, function(err, todo) {
if (err)
res.send(err);
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err)
res.send(err)
res.json(todos);
});
});
});
// delete a todo
app.delete('/api/todos/:todo_id', function(req, res) {
Todo.remove({
_id : req.params.todo_id
}, function(err, todo) {
if (err)
res.send(err);
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err)
res.send(err)
res.json(todos);
});
});
});
// application -------------------------------------------------------------
app.get('*', function(req, res) {
res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});
};
There are 2 ways - you can use $http.put bu you can also use $resource. I hope that this will help you
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-resource.min.js"></script>
<script type="text/javascript" src="angularjs_app.js"></script>
</head>
<body>
<div ng-controller="MainController">
<form name="todoForm" novalidate>
<label>Id</label>
<input type="text" name="_id" ng-model="editTodo._id">
<br/>
<label>Subject</label>
<input type="text" name="subject" ng-model="editTodo.subject">
<br/>
<label>Description</label>
<input type="text" name="desc" ng-model="editTodo.desc">
<br/>
<button ng-click="updateTodo()">Update Todo</button>
</form>
</div>
</body>
</html>
angularjs_app.js (1 Way)
var myApp = angular.module('myApp', []);
myApp.controller('MainController', ['$scope',
function($scope) {
$scope.updateTodo = function() {
$http.put('/api/todos/' + $scope.editTodo._id, $scope.editTodo).success(function() {
alert('Todo updated');
});
// Or you can try
// $http.put('/api/todos/' + $scope.editTodo._id, {"todo": $scope.editTodo})
// .success(function(data, status, headers, config){
// $scope.editTodo = data.todo;
// })
// .error(function(data, status, headers, config){
// alert(data.error_message);
// });
};
}]);
angularjs_app.js (2 Way)
var myApp = angular.module('myApp', ['ngResource', 'myAppServices']);
myApp.controller('MainController', ['$scope', 'TodoFactory',
function($scope, TodoFactory) {
$scope.updateTodo = function() {
TodoFactory.update($scope.editTodo, function() {
alert('Todo updated');
});
};
}]);
var myAppServices = angular.module('myAppServices', ['ngResource']);
myAppServices.factory('TodoFactory', ['$resource',
function($resource) {
return $resource('/api/todos/:todoId', {}, {
update: {method:'PUT', params: {todoId: '#_id'}}
});
}
]);
nodejs_server.js
var express = require('express');
var path = require('path');
var http = require('http');
var todos = require('./routes_todos');
var app = express();
app.configure(function() {
app.set('port', process.env.PORT || 3000);
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
});
app.get('/api/todos', todos.findAll);
app.get('/api/todos/:id', todos.findById);
app.post('/api/todos', todos.add);
app.put('/api/todos/:id', todos.update);
app.delete('/api/todos/:id', todos.remove);
http.createServer(app).listen(app.get('port'), function() {
console.log("Express server listening on port " + app.get('port'));
});
routes_todos.js
var mongo = require('mongodb');
var Server = mongo.Server;
var Db = mongo.Db;
var BSON = mongo.BSONPure;
var server = new Server('localhost', 27017, {auto_reconnect: true});
db = new Db('todosdb', server);
db.open(function(err, db) {
if (!err) {
console.log("Connected to 'todosdb' database");
db.collection('todos', {strict: true}, function(err, collection) {
if (err) {
console.log("Error todos does not exist");
}
});
}
});
exports.findAll = function(req, res) {
db.collection('todos', function(err, collection) {
collection.find().toArray(function(err, items) {
console.log('todos send from DB');
res.send(items);
});
});
};
exports.findById = function(req, res) {
var id = req.params.id;
console.log('Retrieving todo: ' + id);
db.collection('todos', function(err, collection) {
collection.findOne({'_id': new BSON.ObjectID(id)}, function(err, item) {
res.send(item);
});
});
};
exports.add = function(req, res) {
var todo = req.body;
console.log('Adding todo: ' + JSON.stringify(todo));
db.collection('todos', function(err, collection) {
collection.insert(todo, {safe: true}, function(err, result) {
if (err) {
res.send({'error': 'An error has occurred'});
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
});
});
};
exports.update = function(req, res) {
var id = req.params.id;
var todo = req.body;
console.log('Updating todo: ' + id);
console.log(JSON.stringify(todo));
delete todo._id;
db.collection('todos', function(err, collection) {
collection.update({'_id': new BSON.ObjectID(id)}, todo, {safe: true}, function(err, result) {
if (err) {
console.log('Error updating todo: ' + err);
res.send({'error': 'An error has occurred'});
} else {
console.log('' + result + ' document(s) updated');
res.send(todo);
}
});
});
};
exports.remove = function(req, res) {
var id = req.params.id;
console.log('Removing todo: ' + id);
db.collection('todos', function(err, collection) {
collection.remove({'_id': new BSON.ObjectID(id)}, {safe: true}, function(err, result) {
if (err) {
res.send({'error': 'An error has occurred - ' + err});
} else {
console.log('' + result + ' document(s) removed');
res.send(req.body);
}
});
});
};
Related
i cloned an node.js application and , to set up, i did an npm install and npm install -g nodemon , i wanted to run it locally on port 3000, so in my app.js file i added
app.listen(3000, () => console.log('Server running on port 3000!'))
and then i tried to run it by using node app.js but i am getting this errors
this is my app.js file
var express = require('express');
var engine = require('ejs-locals');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var fileUpload = require('express-fileupload');
var request = require('request');
var MongoClient = require('mongodb').MongoClient;
var ObjectId = require('mongodb').ObjectID;
var routes = require('./routes/index');
var testgrid = require('./routes/testgrid');
var hsdes_query = require('./routes/hsdes_query');
var find_coverage = require('./routes/find_coverage');
var url = "mongodb://127.0.0.1:27017/onegrid_int";
var config = require('./config');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('ejs', engine);
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(fileUpload());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
var manual_ti_payload_template = {
"attributes": [],
"blackList": "string",
"description": "string",
"endDate": "2019-02-03T21:28:12.567Z",
"id": "string",
"itemId": "string",
"key": "string",
"name": "ascii string",
"namespace": "ascii string",
"ownerIdsid": "string",
"planningAttributes": [],
"resources": [],
"resourcesVersions": [],
"startDate": "2019-02-03T21:28:12.567Z",
"type": "manualitem",
"version": 0,
"whiteList": "string"
}
app.post('/updategtaproc', function(req, res){
console.log("updategtaproc", req.body)
var username = "Lab_FMVPOSumit";
var password = "bdzxl12$";
var auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
request.post( {
url : 'http://gta.intel.com/procedures/api/v1/procedures/' + req.body.name,
headers : {
"Authorization" : auth
},
json: {"description": req.body.description, "steps":req.body.steps}
}, function(error, response, body) {
console.log("updategtaproc response",error, body);
res.send(body)
});
});
app.post('/createnupdategtaproc', function(req, res){
console.log("createnupdategtaproc", req.body)
var username = "Lab_FMVPOSumit";
var password = "bdzxl12$";
var auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
var ti_payload = Object.assign({}, manual_ti_payload_template);
ti_payload.name = req.body.expected;
ti_payload.description = req.body.description;
ti_payload.ownerIdsid = username;
ti_payload.namespace = "vtt-gve-gqe"
console.log(ti_payload)
request.post( {
url : 'https://gta.intel.com/api/tp/v1/testitems',
headers : {
"Authorization" : auth
},
json: ti_payload,
}, function(error, response, body) {
console.log("updategtaproc response",error, body);
if (body && body.itemId) {
console.log("Test case created successfully", body.itemId);
var itemId = body.itemId;
request.post( {
url : 'http://gta.intel.com/procedures/api/v1/procedures/' + body.itemId,
headers : {
"Authorization" : auth
},
json: {"description": req.body.description, "steps":req.body.steps}
}, function(error, response, body) {
console.log("updategtaproc response",error, body);
console.log("Test Procedure Uploaded Successfully");
body['itemId'] = itemId
res.send(body)
});
} else {
console.log("Failed to Create Test Case");
res.send({"message":"Failed To Create Test Case"})
}
});
});
app.post('/getgriditems/:id', function(req, res){
MongoClient.connect(url, function(err, db) {
if(err){
console.log('onegrid_int//getgriditems/:id unable to connect to mongodb')
}
else
{
var collection_name = (req.params.id).toLowerCase() + "-" + "griditems"
var collection = db.collection(collection_name);
var objectIdArr = [];
for (var key in req.body) {
if (req.body.hasOwnProperty(key)) {
item = req.body[key];
try {
objectIdArr.push(ObjectId(String(item)));
}
catch (err)
{
// Invalid Object ID
}
}
}
collection.find({"_id" : {"$in" : objectIdArr }}).toArray(function(err, griditems) {
if(err)
{
console.log('onegrid//getgriditems/:id unable to get grid items')
}
else
{
var paths = []
for ( var r in griditems){
//console.log('path :', result[r]['path'])
paths.push(griditems[r]['path'].join(",") + ',' + griditems[r]['testItem']['itemId'])
}
console.log("paths", paths)
var global_result_collection = db.collection("onegrid-global-results");
global_result_collection.find({"full_path" : {"$in" : paths }}).toArray(function(err, results) {
if(err)
{
console.log('onegrid//getgriditems/:id unable to get test results')
}
else
{
var metadata = {}
metadata['griditems'] = griditems
metadata['results'] = results
console.log("test_results", results)
res.send(metadata);
db.close();
}
});
}
});
}
});
});
app.post('/get_all_tags', function(req, res){
MongoClient.connect(url, function(err, db) {
if(err){
console.log('onegrid/manual_tests/unable to connect to mongodb')
}
else
{
var collection = db.collection('user_tags');
collection.find().toArray(function(err, tags) {
if(err)
{
console.log('onegrid/manual_tests/error getting documents from collection')
}
else
{
var tag_type_ar = tags.map(a => a.type_tag);
//console.log('onegrid/manual_tests/number_of_docs/', tests.length)
//console.log('onegrid/manual_tests/tags/', tags_name)
res.send(tag_type_ar);
db.close();
}
});
}
});
});
app.post('/getsettags', function(req, res){
//console.log('body: ' + JSON.stringify(req.body));
var url = "mongodb://127.0.0.1:27017/onegrid";
MongoClient.connect(url, function(err, db) {
if(err){
console.log('onegrid/getsettags/unable to connect to mongodb')
}
else
{
var objectId = ObjectId(req.body.id);
var collection = db.collection('gve_manual_testitems');
if(req.body.op == 'set_add') {
collection.findOne({ _id : objectId }, function(err, result) {
if(err)
{
console.log('onegrid/getsettags/set/unable to get test item id', objectId)
}
else
{
//console.log('onegrid/getsettags/set/test item id current tag value', result['tags'])
if(result['tags'] && result['tags'].indexOf(req.body.newtag) != -1) {
res.send(result);
db.close();
}
else {
if(result['tags'])
{
result['tags'].push(req.body.newtag)
}
else
{
result['tags'] = [req.body.newtag];
}
collection.updateOne({ _id : objectId }, { $set: { "tags" : result['tags'] } }, function(err, result) {
if(err)
{
console.log('onegrid/getsettags/set/unable to set tags')
}
else
{
console.log('tags added successfully to test item');
var test_tags = result;
if(!req.body.skip_tag_source_update) {
var user_tags = db.collection('user_tags');
var type_tag = req.body.newtag;
var type = req.body.newtag.split(":")[0]
var tag = req.body.newtag.split(":")[1]
var tag_obj = {'type':type, 'tag': tag, 'type_tag' : type_tag}
user_tags.insertOne(tag_obj, function(err, result) {
if(err)
{
console.log('onegrid/getsettags/set unable to add to user tag')
}
else
{
console.log('tags added to user_tags')
res.send(test_tags);
db.close();
}
});
}
else
{
res.send(test_tags);
db.close();
}
//var newtag = req.body.newtag;
//var tag_type = newtag.split(":")[0];
//var tag_name = newtag.split(":")[1];
//console.log(tag_type,tag_name)
}
});
}
}
});
}
if(req.body.op == 'set_remove') {
collection.findOne({ _id : objectId }, function(err, result) {
if(err)
{
console.log('onegrid/getsettags/set/unable to get test item id', objectId)
}
else
{
//console.log('onegrid/getsettags/set/test item id current tag value', result['tags'])
result['tags'].splice(result['tags'].indexOf(req.body.newtag),1);
//console.log('onegrid/getsettags/set/test item id current tag value', result['tags'])
collection.updateOne({ _id : objectId }, { $set: { "tags" : result['tags'] } }, function(err, result) {
if(err)
{
console.log('onegrid/getsettags/set/unable to set tags')
}
else
{
console.log('tags removed successfully')
//collection = db.collection('user_tags');
//var newtag = req.body.newtag;
//var tag_type = newtag.split(":")[0];
//var tag_name = newtag.split(":")[1];
//console.log(tag_type,tag_name)
res.send(result);
db.close();
}
});
}
});
}
if(req.body.op == 'get') {
collection.findOne({ _id : objectId }, function(err, result) {
if(err)
{
console.log('onegrid/manual_tests/unable to get tags')
}
else
{
//console.log('tags retrieved successfully ', result['tags'])
if(result['tags'])
res.send(result['tags'].join(","));
else
res.send("");
db.close();
}
});
}
}
});
});
app.post('/gettestprocs/:id', function(req, res){
console.log('gettestprocs body: ' + (req.body.itemId));
//var url = "mongodb://127.0.0.1:27017/og1";
MongoClient.connect(url, function(err, db) {
if(err){
console.log('onegrid/manual_tests/unable to connect to mongodb')
}
else
{
var collection_name = (req.params.id).toLowerCase() + "-" + "testprocs"
var collection = db.collection(collection_name);
collection.findOne({ "id" : req.body.itemId },function(err, result) {
if(err)
{
console.log('onegrid/manual_tests/unable to get tags')
}
else
{
console.log('test proc:', result)
res.send(result);
db.close();
}
});
}
});
});
app.post('/gettestprocsbyitemid', function(req, res){
//console.log('gettestprocs body: ' + (req.body));
var url = "mongodb://127.0.0.1:27017/onegrid_int";
MongoClient.connect(url, function(err, db) {
if(err){
console.log('onegrid/manual_tests/unable to connect to mongodb')
}
else
{
console.log(req.body)
/*if(String(req.body.grid_type) == "MANUAL"){
collection_name = "n_gve_manual_testprocs"
} else if(String(req.body.grid_type) == "OLD_MANUAL") {
collection_name = "gve_manual_testprocs"
} else if(String(req.body.grid_type) == "SURFACE") {
collection_name = "gve_surface_testprocs"
}
else if(String(req.body.grid_type) == "AUTO") {
}*/
//var tp = testplans.filter(function(x){return x.itemId == req.params.id})[0];
var collection_name = (req.body.testplan_id).toLowerCase() + "-" + "testprocs"
var collection = db.collection(collection_name);
collection.findOne({"id" : String(req.body.proc_id) },function(err, result) {
if(err)
{
console.log('onegrid/manual_tests/unable to get tags')
}
else
{
console.log('test proc:', result)
res.send(result);
db.close();
}
});
}
});
});
app.use('/', routes);
app.use('/testgrid', testgrid);
app.use('/hsdes_query', hsdes_query);
app.use('/find_coverage', find_coverage);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
app.listen(3000, () => console.log('Server running on port 3000!'))
module.exports = app;
another app.js in C:\projects\New Project\onegrid\web\node_modules\ejs-locals\example
var express = require('express')
, engine = require('../')
, app = express();
// use ejs-locals for all ejs templates:
app.engine('ejs', engine);
app.set('views',__dirname + '/views');
app.set('view engine', 'ejs'); // so you can render('index')
// render 'index' into 'boilerplate':
app.get('/',function(req,res,next){
res.render('index', { what: 'best', who: 'me', muppets: [ 'Kermit', 'Fozzie', 'Gonzo' ] });
});
app.get('/foo.js', function(req,res,next){
res.sendfile('foo.js');
})
app.get('/foo.css', function(req,res,next){
res.sendfile('foo.css');
})
app.listen(3000);
what am i doing wrong , i just want to run it on localhost 3000. ?
Your terminal shows you running node server.js but your file is called app.js.
I'm trying to get a "success" or "failure" response from my server to client. The server is being implemented in node.js in express framework and the client in angularjs.
Here is the server side node.js part:
connection.connect();
/* GET home page. */
router.get('/', function(req, res, next) {
res.sendFile(path.join(__dirname, '../', 'views', 'login.html'));
});
router.get('/login', function(req,res)
{
console.log("Username:"+req.query.username);
console.log("Password:"+req.query.password);
var user = req.query.username;
var pass = req.query.password
connection.query("select * from user where login_name = ?", user, function(err, rows, fields) {
if (!err){
if(user==rows[0].login_name && pass==rows[0].pass){
console.log("success");
res.json({status: 200});
}
}
else
console.log('Error while performing Query.', err);
});
and here is the angularjs part:
<form name="login">
<div class="login" ng-app="loginPage" ng-controller="loginController">
<input type="text" placeholder="username" ng-model="uname" name="userid"><br>
<input type="password" placeholder="password" ng-model="pword" name="pswrd"><br>
<!--<input type="button" ng-click="login();" onclick="check(this.form)" value="Login"/>-->
<button ng-click="login();">Login</button>
</div>
</form>
<script language="javascript">
var app = angular.module('loginPage', []);
app.controller('loginController', function($scope, $http) {
console.log("inside controller");
$scope.login = function() {
console.log("inside the login function");
console.log($scope.uname);
var verify = $http({
method: 'GET',
url: '/login' +
'',
params: { username: $scope.uname, password: $scope.pword }
}).then(
function successful(response) {
$scope.theResponse = response.data;
window.open("./team_list.html")
}, function unsuccessful(response) {
alert('Wrong username/password.');
$scope.theResponse = response.data;
});
}
})
</script>
I try to type in "test" for username and "test" for pw on the login page on the browser because that is what I have entered in my sql database. Specifically I'm not sure why the login page doesn't link to the team_list page that I have specified the path for.
I'm not really sure why it's not working. If I'm supposed to be using json differently, I would appreciate more help because I am not very familiar with it.
The order of the routing in the NodeJS side is wrong. The /login should come first. Else everything will be served by the '/' route.
router.get('/login', function(req, res) {
console.log("Username:" + req.query.username);
console.log("Password:" + req.query.password);
var user = req.query.username;
var pass = req.query.password
connection.query("select * from user where login_name = ?", user, function(err, rows, fields) {
if (!err) {
if (user == rows[0].login_name && pass == rows[0].pass) {
console.log("success");
res.json({
status: 200
});
}
} else
console.log('Error while performing Query.', err);
});
/* GET home page. */
router.get('/', function(req, res, next) {
res.sendFile(path.join(__dirname, '../', 'views', 'login.html'));
});
Check your console you can even figure out the problem from there.
Shortcuts for console
shortcut keys for opening different browsers's Console
do it like this :
connection.query("select * from user where login_name = ?", user, function(err, rows, fields) {
if (!err){
if(user==rows[0].login_name && pass==rows[0].pass){
console.log("success");
res.send(200);
}
}
else{
console.log('Error while performing Query.', err);
res.send(401);
}
});
Actually, you should send Error or Success code like 200 or 401.
And use
res.send(ErrorCode) or res.sendStatus(ErrorCode) and it'll autmatically do it for you at client side like below :
<script language="javascript">
var app = angular.module('loginPage', []);
app.controller('loginController', function($scope, $http, $window) {
console.log("inside controller");
$scope.login = function() {
console.log("inside the login function");
console.log($scope.uname);
$http.get('/login').then(function (success) {
$window.alert('Success');
}, function (error) {
$window.alert('Wrong username/password.');
});
}
});
</script>
I'm trying to update an array in one of my database objects.
I'm checking the object before making a put request. But the object won't update in my MongoDB database.
client/entry/newEntry.controller.js:
$scope.save = function(form) {
$scope.submitted = true;
$scope.entry.date = Date.now;
$scope.entry.writer = $scope.getCurrentUser;
$scope.entry.type = 'chapter';
getHighestArticleId();
$scope.entry.articleId = articleId;
if(form.$valid) {
$http.post('/api/entrys', $scope.entry)
.success(function(data){
console.log(' -- posted entry --');
console.log('data: ', data);
$scope.entry = data;
console.log($scope.entry.orphan);
if($scope.entry.orphan == false){
$scope.parent.children.push($scope.entry);
console.log(' -- parent to update --');
console.log($scope.parent);
$http.put('/api/entrys/' + $scope.parent._id)
.success(function(data){
console.log(' -- updated parent --');
console.log(data);
});
}
});
}
};
entry api/entry/index.js:
'use strict';
var express = require('express');
var controller = require('./entry.controller');
var router = express.Router();
router.get('/', controller.index);
router.get('/:id', controller.show);
router.get('/:id/children/', controller.getChildren);
router.get('/type/:type', controller.getByType);
router.get('/type/:type/orphan/:hasParent', controller.getByTypeAndOrphan);
router.post('/', controller.create);
router.put('/:id', controller.update);
router.patch('/:id', controller.update);
router.delete('/:id', controller.destroy);
module.exports = router;
api/entry/entry.controller.js:
// Updates an existing entry in the DB.
exports.update = function(req, res) {
if(req.body._id) {
delete req.body._id;
}
Entry.findById(req.params.id, function (err, entry) {
if (err) {
return handleError(res, err);
}
if(!entry) {
return res.send(404);
}
var updated = _.merge(entry, req.body);
updated.save(function (err) {
if (err) {
return handleError(res, err);
}
return res.json(200, entry);
});
});
};
EDIT
routes.js:
/**
* Main application routes
*/
'use strict';
var errors = require('./components/errors');
module.exports = function(app) {
// Insert routes below
app.use('/api/languages', require('./api/language'));
app.use('/api/forums', require('./api/forum'));
app.use('/api/entrys', require('./api/entry'));
app.use('/api/things', require('./api/thing'));
app.use('/api/users', require('./api/user'));
app.use('/auth', require('./auth'));
// All undefined asset or api routes should return a 404
app.route('/:url(api|auth|components|app|bower_components|assets)/*')
.get(errors[404]);
// All other routes should redirect to the index.html
app.route('/*')
.get(function(req, res) {
res.sendfile(app.get('appPath') + '/index.html');
});
};
Found the answer. The problem was in three places. The first in my call to the api
$http.put('/api/entrys/' + $scope.parent._id)
.success(function(data){
console.log(' -- updated parent --');
console.log(data);
});
should instead be
$http.put('/api/entrys/' + $scope.parent._id, $scope.parent)
.success(function(data){
console.log(' -- updated parent --');
console.log(data);
});
The second problem was my child object. I passed the entire object, but only needed the id, so my push should change from this
$scope.parent.children.push($scope.entry);
to this
$scope.parent.children.push($scope.entry._id);
Finally my update function itself needed to be informed that I was handling the sub-document. Which meant that I had to add this to the function
// Updates an existing entry in the DB.
exports.update = function(req, res) {
if(req.body._id) {
delete req.body._id;
}
Entry.findById(req.params.id, function (err, entry) {
if (err) {
return handleError(res, err);
}
if(!entry) {
return res.send(404);
}
var updated = _.merge(entry, req.body);
entry.markModified('children');
updated.save(function (err) {
if (err) {
return handleError(res, err);
}
return res.json(200, entry);
});
});
};
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);
}
});
}
}
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/