can't delete record from mongodb dbase using backbone.js - javascript

Following "Developing Backbone js" http://addyosmani.github.io/backbone-fundamentals/#talking-to-the-server (search "parse function")
on click "Delete": the book is not deleted from the server (dbase) even with this "parse" function operating OK... the DELETE http command is given, with the correct ID for the book... but this doesn't delete it from the dbase...
generated URL command looks like this:
DELETE http://localhost:4711/api/books/5417ff846b205d9c05000001
... this is triggering the following function in server.js
app.delete( '/api/books/:id', function( request, response ) {
console.log( 'Deleting book with id: ' + request.params.id );
...
... but the DELETE command never "returns" (in FF Console you just get the spinner, which doesn't go away)...

In your server.js, setup your server as follows:
// Module dependencies.
var application_root = __dirname,
express = require("express"), // Web framework
path = require("path"), // Utilities for dealing with file paths
mongoose = require('mongoose'); // MongoDB integration
//Create server
var app = express.createServer();
// Configure server
app.configure(function () {
app.use(express.bodyParser()); // parses request body and populates req.body
app.use(express.methodOverride()); // checks req.body for HTTP method overrides
app.use(app.router); // perform route lookup based on url and HTTP method
app.use(express.static(path.join(application_root, "public"))); // Where to serve static content
app.use(express.errorHandler({ dumpExceptions:true, showStack:true })); // Show all errors in development
});
//Start server
app.listen(4711, function () {
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});
// Connect to database
mongoose.connect('mongodb://localhost/library_database');
//Schemas
var Book = new mongoose.Schema({
title:String,
author:String,
releaseDate: Date
});
//Models
var BookModel = mongoose.model('Book', Book);
Try creating the delete route as follows:
app.delete('/api/books/:id', function(req, res){
console.log('Deleting book with id: ' + req.params.id);
return BookModel.findById(req.params.id, function(err, book){
return book.remove(function(err){
if(!err){
console.log('Book removed');
return res.send('');
} else {
console.log(err);
}
});
});
});
And test it via AJAX:
$.ajax({
url:'/api/books/5417ff846b205d9c05000001',
type: 'DELETE',
success:function(data, textStatus, jqXHR){
console.log("Post resposne:");
console.dir(data);
console.log(textStatus);
console.dir(jqXHR);
}
});

Related

Node.js parsing form data using formidable

Hey guys I am new to node, and trying to setup a file/image upload script.
I was able to setup node on my VPS and following this example I also set up the app and it is working great.
https://coligo.io/building-ajax-file-uploader-with-node/
It is using formidable and express
However I'd love to also parse a form where people can add their name and the files get uploaded into a folder containing their names.
I was able to get the folder creation working using mkdirp, however even after many hours of research (formidable api, express api, and more) I can't get the form to parse the name.
I suspect that the upload.js (which sends the data to the node app) does not work.
At the moment a new folder with a random string is created for each upload, but I'd love to be able to parse the entered formname.
Any idea how to get it working? I'd appreciate any help/hints.
app.js
var express = require('express');
var app = express();
var path = require('path');
var formidable = require('formidable');
var fs = require('fs');
var mkdirp = require('mkdirp');
var crypto = require("crypto");
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, 'views/index.html'));
});
app.post('/upload', function(req, res){
var ordner = crypto.randomBytes(20).toString('hex');
mkdirp('/home/myfolder/fileupload/'+ordner, function (err) {
if (err) console.error(err)
else console.log(ordner)
});
var form = new formidable.IncomingForm();
form.multiples = true;
form.uploadDir = path.join(__dirname, '/'+ ordner);
form.on('file', function(field, file) {
fs.rename(file.path, path.join(form.uploadDir, file.name + Date.now()+'.jpg'));
});
form.on('field', function(field, userName) {
console.log(userName);
});
form.on('error', function(err) {
console.log('An error has occured: \n' + err);
});
form.on('end', function() {
res.end('success');
});
form.parse(req);
});
var server = app.listen(3000, function(){
console.log('Server listening on port 3000');
});
Thanks
The upload.js is unchanged and I simply added another input to the view.
You can do this by sending the parameters through the POST like so
app.post('/upload/:userName', function(req, res){
var username = req.params.userName
mkdirp('/home/myfolder/fileupload/'+username, function (err) {
if (err) console.error(err)
else console.log(ordner)
});
The rest of your code pretty much stays the same.
EDIT: Your ajax would look something like this
var username = 'GetThisValueFromTheUser'
$.ajax({
url: '/upload'+username,
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(data){
console.log('upload successful!');
}
});
Note: You can send parameters by using /:parameter in your POST or GET requests, from then on it is easy to use those parameters however you want.

Nodejs - Express res.download giving Can't set headers after they are sent exception

I want to make an api that will serve files of any extensions.
Like this: http://localhost/download/[file].[extension]
Here is my code, but it is intermittently giving this message: Can't set headers after they are sent.
var express = require('express');
var app = express();
app.get('/download/:fileName/:extension', function(req, res){
var file = __dirname + '/' + req.params.fileName + '.' + req.params.extension;
res.download(file, function(err){
if (err) {
res.sendStatus(404);
}
res.end();
});
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('app listening at http://%s:%s', host, port);
});
res.download has already sent a response (Not always true in the case of an error though)
You can fix this by doing
res.download(file, function(err){
if(err) {
// Check if headers have been sent
if(res.headersSent) {
// You may want to log something here or do something else
} else {
return res.sendStatus(SOME_ERR); // 404, maybe 500 depending on err
}
}
// Don't need res.end() here since already sent
}
Other changes called out in the comments above:
download uses sendFile, which you don't need res.end() after
download's documentation warns that you need to check res.headersSent when handling errors, as the headers may already be sent, which would mean you can't change the status

Save a JSON file to server in express (node)

Having this function in express that writes a JSON file on a folder
var savingtheJson=function(path, jsonObject, callback){
jsonfile.writeFile(file2, jsonO, callback);
}
I will like to know how can I access/read this file from the browser once is saved.
If I do this:
savingtheJson('/json/myfile.json', jsonObj, function(){
console.log("done it!");
});
When I go to the browser and I type:
http://localhost:8080/json/myfile.json
Of course I get an error from express "Cannot Get ...." cause I think is trying to resolve it like an specific request
How can I store this file into the static folder declared for this goal
(app.use(express.static(__dirname + '/public'))?
How can I access this file once is saved?
First you need to define which folder is going to be exposed as public, so that you can save your json file inside there.
You can use the built-in middleware express.static for this purpose.
Below in the example I have created a endpoint called /users?name=wilson&age=32 which receives query data in order grab user's information as name and age for then you can save it as file named person.json.
So after you consume the above endpoint mentioned, you will be able to consume your file with something like http://localhost:4040/person.json successfully.
var express = require('express');
var app = express();
var port = 4040;
var fs = require('fs');
app.use(express.static('public'));
app.get('/users', function(req, res) {
var name = req.query.name;
var age = req.query.age;
var person = {
name: name,
age: age
};
savePersonToPublicFolder(person, function(err) {
if (err) {
res.status(404).send('User not saved');
return;
}
res.send('User saved');
});
});
function savePersonToPublicFolder(person, callback) {
fs.writeFile('./public/person.json', JSON.stringify(person), callback);
}
app.listen(port, function() {
console.log('server up and running at port: %s', port);
});

Node.js app giving ERR_EMPTY_RESPONSE

I'm having serious issues with an app I am building with Node.js, Express, MongoDB and Mongoose. Last night everything seemed to work when I used nodemon server.js to `run the server. On the command line everything seems to be working but on the browser (in particular Chrome) I get the following error: No data received ERR_EMPTY_RESPONSE. I've tried other Node projects on my machine and they too are struggling to work. I did a npm update last night in order to update my modules because of another error I was getting from MongoDB/Mongoose { [Error: Cannot find module '../build/Release/bson'] code: 'MODULE_NOT_FOUND'}. I used the solution in this answer to try and fix it and it didn't work and I still get that error. Now I don't get any files at all being served to my browser. My code is below. Please help:
//grab express and Mongoose
var express = require('express');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//create an express app
var app = express();
app.use(express.static('/public/css', {"root": __dirname}));
//create a database
mongoose.connect('mongodb://localhost/__dirname');
//connect to the data store on the set up the database
var db = mongoose.connection;
//Create a model which connects to the schema and entries collection in the __dirname database
var Entry = mongoose.model("Entry", new Schema({date: 'date', link: 'string'}), "entries");
mongoose.connection.on("open", function() {
console.log("mongodb is connected!");
});
//start the server on the port 8080
app.listen(8080);
//The routes
//The route for getting data for the database
app.get("/database", function(req, res) {
Entry.find({}, function(err, data) {console.log(err, data, data.length); });
});
//The route for posting data on the database
app.post("/database", function(req, res) {
//test new post
var newMonth = new Entry({date: '1997-10-30', link: 'https://wwww.youtube.com/'});
newMonth.save(function(err) {
if (err !== null) {
//object was not save
console.log(err);
} else {
console.log("it was saved!")
};
});
});
//create an express route for the home page at http://localhost:8080/
app.get('/', function(req, res) {
res.send('ok');
res.sendFile('/views/index.html', {"root": __dirname + ''});
});
//Send a message to the console
console.log('The server has started');
//The route for getting data for the database
app.get("/database", function(req, res) {
Entry.find({}, function(err, data) {console.log(err, data, data.length); });
});
//The route for posting data on the database
app.post("/database", function(req, res) {
//test new post
var newMonth = new Entry({date: '1997-10-30', link: 'https://wwww.youtube.com/'});
newMonth.save(function(err) {
if (err !== null) {
//object was not save
console.log(err);
} else {
console.log("it was saved!")
};
});
});
These routes don't send anything back to the client via res. The bson error isn't a big deal - it's just telling you it can't use the C++ bson parser and instead is using the native JS one.
A fix could be:
//The route for getting data for the database
app.get("/database", function(req, res) {
Entry.find({}, function(err, data) {
if (err) {
res.status(404).json({"error":"not found","err":err});
return;
}
res.json(data);
});
});
//The route for posting data on the database
app.post("/database", function(req, res) {
//test new post
var newMonth = new Entry({date: '1997-10-30', link: 'https://wwww.youtube.com/'});
newMonth.save(function(err) {
if (err !== null) {
res.status(500).json({ error: "save failed", err: err});
return;
} else {
res.status(201).json(newMonth);
};
});
});
updated june 2020
ERR_EMPTY_RESPONSE express js
package.json
"cors": "^2.8.4",
"csurf": "^1.9.0",
"express": "^4.15.4",
this error show when you try to access with the wrong HTTP request. check first your request was correct
maybe your cors parameter wrong

Socket.io is not working with my node/express application

I am using openshift with express and no matter what configuration I change socket.io to it breaks my application. What am I missing?
I have commented out the sections that use socket.io and the app runs fine.
When I uncomment socket.io everything goes wrong. I have tried changing the position of the code to accept the standard io.listen(app), but it still breaks. I have also tried numerous examples from the internet.
Is this possible? //self.io.listen(self.app); if not what should I have socket.io listen to in the context of my app? I cannot call io.listen(server)..
var express = require('express');
//etc
// configuration
mongoose.connect(configDB.url); // connect to our database
require('./config/passport')(passport);
var App = function(){
// Scope
var self = this;
// Setup
self.dbServer = new mongodb.Server(process.env.OPENSHIFT_MONGODB_DB_HOST,parseInt(process.env.O PENSHIFT_MONGODB_DB_PORT));
self.db = new mongodb.Db(process.env.OPENSHIFT_APP_NAME, self.dbServer, {auto_reconnect: true});
self.dbUser = process.env.OPENSHIFT_MONGODB_DB_USERNAME;
self.dbPass = process.env.OPENSHIFT_MONGODB_DB_PASSWORD;
self.ipaddr = process.env.OPENSHIFT_NODEJS_IP;
self.port = parseInt(process.env.OPENSHIFT_NODEJS_PORT) || 8080;
if (typeof self.ipaddr === "undefined") {
console.warn('No OPENSHIFT_NODEJS_IP environment variable');
};
// Web app urls
self.app = express();
//self.io = require('socket.io');
//self.clients = [];
/*self.io.sockets.on('connection', function (socket) {
self.clients.push(socket);
socket.emit('welcome', { message: 'Welcome!' });
// When socket disconnects, remove it from the list:
socket.on('disconnect', function() {
var index = self.clients.indexOf(socket);
if (index != -1) {
self.clients.splice(index, 1);
}
});
});*/
// set up our express application
self.app.use(morgan('dev')); // log every request to the console
self.app.use(cookieParser()); // read cookies (needed for auth)
self.app.use(bodyParser.json()); // get information from html forms
self.app.use(bodyParser.urlencoded({ extended: true }));
self.app.use(bodyParser());
self.app.use(multer({ dest: process.env.OPENSHIFT_DATA_DIR}));
self.app.use(compression());
self.app.use(express.static(__dirname + '/public'));
self.app.use("/public2", express.static(process.env.OPENSHIFT_DATA_DIR));
self.app.set('view engine', 'ejs'); // set up ejs for templating
self.app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', 'true');
next();
}
);
// required for passport
self.app.use(session({
secret:'example',
maxAge: 6 * 3 * 60 * 1000,
store: new MongoStore({ url: process.env.OPENSHIFT_MONGODB_DB_URL,
clear_interval: 6 * 3 * 60 * 1000 })
}));
self.app.use(passport.initialize());
self.app.use(passport.session()); // persistent login sessions
self.app.use(flash()); // use connect-flash for flash messages stored in session
require('./app/routes.js')(self.app, passport); // load our routes and pass in our app and fully configured passport
self.connectDb = function(callback){
self.db.open(function(err, db){
if(err){ throw err };
self.db.authenticate(self.dbUser, self.dbPass, {authdb: "admin"}, function(err, res){
if(err){ throw err };
callback();
});
});
};
//starting the nodejs server with express
self.startServer = function(){
self.app.listen(self.port, self.ipaddr, function(){
console.log('%s: Node server started on %s:%d ...', Date(Date.now()), self.ipaddr, self.port);
});
//websockets
//self.io.listen(self.app);
};
// Destructors
self.terminator = function(sig) {
if (typeof sig === "string") {
console.log('%s: Received %s - terminating Node server ...', Date(Date.now()), sig);
process.exit(1);
};
console.log('%s: Node server stopped.', Date(Date.now()) );
};
process.on('exit', function() { self.terminator(); });
self.terminatorSetup = function(element, index, array) {
process.on(element, function() { self.terminator(element); });
};
['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT', 'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGPIPE', 'SIGTERM'].forEach(self.terminatorSetup);
};
//make a new express app
var app = new App();
//call the connectDb function and pass in the start server command
app.connectDb(app.startServer);
Thank you for your comments. The solution was to create a self.server variable to pass the express server into socket.io. I have tested the connection and it is working fine now; with all of the other server dependencies.
//starting the nodejs server with express
self.startServer = function(){
self.server = self.app.listen(self.port, self.ipaddr, function(){
console.log('%s: Node server started on %s:%d ...', Date(Date.now()), self.ipaddr, self.port);
});
//websockets
self.io = require('socket.io').listen(self.server);
};

Categories