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);
});
});
};
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
I am using mlab and mongojs along with Angular. When I attempt to toggle a boolean value (onStatus), the button in the view toggles from off to on, but it crashes the app. When I check in the DB the property has been removed from the document. Code snippets below:
device.service.ts
toggleDevice(updatedStatus){
var headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.put('/api/device/'+updatedStatus._id, JSON.stringify(updatedStatus), {headers: headers})
.map(res => res.json());
}
devices.component.ts
toggleDevice(device){
var currentStatus = device.onStatus;
var updatedStatus = {
_id: device._id,
name: device.name,
onStatus: !currentStatus
};
this.deviceService.toggleDevice(updatedStatus)
.subscribe(data => {
device.onStatus = !device.onStatus
});
}
devices.compoonents.html
<button class="btn" (click)="toggleDevice(device)" type="button">{{ device.onStatus ? 'Switch Off' : 'Switch On' }}</button>
API routing
var express = require('express');
var router = express.Router();
var database = require('../config/database');
var mongojs = require('mongojs');
var db = mongojs(database.url, ['devices'])
// GET : All devices
router.get('/devices', function(req, res, next){
db.devices.find(function(err, devices){
if(err) {
res.send(err);
}
res.json(devices);
});
});
// GET : Single device
router.get('/device/:id', function(req, res, next){
db.devices.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
if(err) {
res.send(err);
}
res.json(device);
});
});
// POST : Save a device
router.post('/device', function(req, res, next){
var device = req.body;
device.onStatus = false;
if(!device.name) {
res.status(400);
res.json({
"error": "Please add a name."
});
} else {
db.devices.save(device, function(err, device){
if(err) {
res.send(err);
}
res.json(device);
});
}
});
// DELETE : A device
router.delete('/device/:id', function(req, res, next){
db.devices.remove({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
if(err) {
res.send(err);
}
res.json(device);
});
});
// PUT : Update a device
router.put('/device/:id', function(req, res, next){
var device = req.body;
var updatedDevice = {};
if(device.name) {
updatedDevice.name = device.name;
}
if(!updatedDevice){
res.status(400);
res.json({'Error': 'Name not specified'});
} else {
db.devices.update({_id: mongojs.ObjectId(req.params.id)}, updatedDevice, {}, function(err, device){
if(err) {
res.send(err);
}
res.json(device);
});
}
db.devices.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
if(err) {
res.send(err);
}
res.json(device);
});
});
module.exports = router;
Errors
/home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/lib/utils.js:98
process.nextTick(function() { throw err; });
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
at ServerResponse.header (/home/chopin/Development/homeautomation/node_modules/express/lib/response.js:719:10)
at ServerResponse.send (/home/chopin/Development/homeautomation/node_modules/express/lib/response.js:164:12)
at ServerResponse.json (/home/chopin/Development/homeautomation/node_modules/express/lib/response.js:250:15)
at /home/chopin/Development/homeautomation/routes/devices.js:80:9
at /home/chopin/Development/homeautomation/node_modules/mongojs/lib/collection.js:50:5
at handleCallback (/home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/lib/utils.js:95:56)
at /home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/lib/cursor.js:674:5
at handleCallback (/home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:171:5)
at nextFunction (/home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:682:5)
[nodemon] app crashed - waiting for file changes before starting...
Thanks for any help.
EDIT: I should mention the error only occurs the 2nd time I toggle the button. I am assuming as this has been removed from DB for some reason. The name of and ID persist, yet the onStatus doesn't.
EDIT 2: Full code https://github.com/Sacki2013/homeAutomation
You are trying send the response even after it is already sent. All you have to do is that add return statements after your response is sent.
var express = require('express');
var router = express.Router();
var database = require('../config/database');
var mongojs = require('mongojs');
var db = mongojs(database.url, ['devices'])
// GET : All devices
router.get('/devices', function(req, res, next){
db.devices.find(function(err, devices){
if(err) {
res.send(err);
return;
}
res.json(devices);
});
});
// GET : Single device
router.get('/device/:id', function(req, res, next){
db.devices.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
if(err) {
res.send(err);
return;
}
res.json(device);
});
});
// POST : Save a device
router.post('/device', function(req, res, next){
var device = req.body;
device.onStatus = false;
if(!device.name) {
res.status(400);
res.json({"error": "Please add a name."});
} else {
db.devices.save(device, function(err, device){
if(err) {
res.send(err);
return;
}
res.json(device);
});
}
});
// DELETE : A device
router.delete('/device/:id', function(req, res, next){
db.devices.remove({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
if(err) {
res.send(err);
return;
}
res.json(device);
});
});
// PUT : Update a device
router.put('/device/:id', function(req, res, next){
var device = req.body;
var updatedDevice = {};
if(device.name) {
updatedDevice.name = device.name;
}
if(!updatedDevice){
res.status(400);
res.json({'Error': 'Name not specified'});
} else {
db.devices.update({_id: mongojs.ObjectId(req.params.id)}, updatedDevice, {}, function(err, device){
if(err) {
res.send(err);
return;
}
/*
* Commenting following line because
* you are sending a response in `findOne`
*/
// res.json(device);
db.devices.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
if(err) {
res.send(err);
return;
}
res.json(device);
});
});
}
});
module.exports = router;
On your /device/:id PUT endpoint you're doing the update and findOne calls asynchronously, independent from each other, so res.json() is called twice. Try moving your findOne function inside the update callback.
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 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/
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);
}
});
});
};