express.js express-resource POST (create) req.body is undefined - node.js

Windows.
Node 0.8 express.js/express-resource
// Configuration of Express Application for all environments
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
//app.use(require('connect').bodyParser());
app.use(express.methodOverride());
app.use(express.static(__dirname + '/public')); // for static assets (css)
app.use(express.static(__dirname + '/..')); // for static assets (css)
app.use(app.router);
});
app.resource("data", require('.....js'));
Send POST /data (in FireBug): account[foo] bar name New
in created method (req, res)
req.body is undefined.
There are some talks in the internet about a like problem (with bodyParser or Router), but I could not fix it.
A

Solved. Just in case for someone: I called app.get(..) before bodyParser middleware.

Related

Nodejs & express can't find public folder

My node.js app can't find the public folder. I've tried using connect static and express static from this answer: static files with express.js and also this answer: File not found in Node.js
But I still can't get it working. I get the content of the page I try to display, but not any of the links to css and js files.
Any ideas?
This is my app.js file.
var express = require('express'),
post = require('./routes/posts'),
web = require('./routes/web'),
http = require('http'),
stylus = require('stylus'),
nib = require('nib'),
path = require('path');
var app = express();
function compile(str, path) {
return stylus(str).set('filename', path).use(nib());
}
app.configure(function () {
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());
app.use(app.router);
app.use(stylus.middleware({src: __dirname + '/public', compile: compile}));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.bodyParser({ keepExtensions: true, uploadDir: __dirname + '/upload/photos' }));
});
//app.use(app.router);
//Web
app.get('/', web.frontPage);
app.post('/posts', post.findAllPosts);
app.post('/posts/:id', post.findPostById);
app.post('/postAdd', post.addPost);
app.put('/posts/:id', post.updatePost);
app.delete('/posts/:id', post.deletePost);
app.get('*', function(req, res){
res.render('404');
});
http.createServer(app).listen(80);
console.log('Listening on port 80...');
Your problem is caused by this:
app.get('*', function(req, res){
res.render('404');
});
Because you're declaring the app.router middleware (which handles that catch-all route) before the static middleware, the router gets all the requests for static files too, and if they aren't handled by any of your other routes, it will generate a 404.
The solution would be to move the static middleware to before the router. The same also needs to be applied to the Stylus middleware and the bodyParser middleware, to make sure they are called before your routes:
app.use(stylus.middleware({src: __dirname + '/public', compile: compile}));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.bodyParser({ keepExtensions: true, uploadDir: __dirname + '/upload/photos' }));
app.use(app.router);
(although it seems that you can skip the bodyParser middleware, since you're using the json, urlencoded and multipart middlewares already; the bodyParser middleware is just a very thin wrapper around those three)

How to add my existing views,stylesheets,javascripts to express?

I have an existing coded frontend i.e views,javascripts,stylesheets (https://github.com/stdrunk/Taskr) and I intend to add this to the express framework so that i can link it to the db.
I added the contents to the public folder. The javascripts in the javascript folder, css in stylesheets, and images in images folder.
Then i changed the code of app.js according to this Render basic HTML view?
Now when run app.js and open the page in the browser i get a stripped version of my original page.
No error comes in the console.
This is my app.js
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
//app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.use(express.static(__dirname + '/public'));
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
app.get('/home', function (req, res)
{
res.render('index.html');
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
You could put all those dirs under a 'public' dir, and then use:
app.use(express.static(__dirname + '/public'));
That way, express will always just send anything requested from those directories, and you won't need to worry about static files at all.
Although, I do recommend keeping something like Apache running on your server to serve static files. Images especially.

how can I access the uploadDir attribute of express?

In express app.js I define uploadDir = "./tmp", but how can I access it later?
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser({uploadDir:'./tmp', keepExtensions: true})); // <--
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
Arguments to middleware like bodyParser go straight through to the middleware. All of the Express middleware is provided by Connect, so it doesn't even know anything about Express. The uploadDir is captured in the multipart closure of the multipart middleware. It is stored via the closure, and never stored anywhere else, or passed to Express, so the only way to access the original value is to access it as part of the options object initially passed in. There is no other way.
If you want that value to be accessible by reading from app(as you said in your comment), then you should set it on there yourself separately. That said, this method is a bit ugly and means that you have to set the value twice.
app.set('uploadDir', './tmp');

ExpressJS 3.0 How to pass res.locals to a jade view?

I want to display a flash message after a user fails to sign in but I just can't get the variables to show up in my Jade views.
I have some pieces, I know I have to use this in my app.configure():
app.use (req, res, next) ->
res.locals.session = req.session
And I'll set what the flash message is after the user POSTS the wrong password:
exports.postSession = (req, res) ->
users = require '../DB/users'
users.authenticate(req.body.login, req.body.password, (user) ->
if(user)
req.session.user = user
res.redirect(req.body.redirect || '/')
else
req.session.flash = 'Authentication Failure!'
res.render('sessions/new', {title:'New', redirect: req.body.redirect })
)
I don't know how to access res.locals.session in my Jade file. I doubt I am setting everything up right. This question is a lot like this one: Migrating Express.js 2 to 3, specifically app.dynamicHelpers() to app.locals.use? but I still can't get it to work. It would be much appreciated if someone could show me just a simple example of setting values in res.local and accessing them in a view.
p.s. I do know about connect-flash but I need to understand how to make things available in views.
This is my app:
app.configure(() ->
app.set('views', __dirname + '/views')
app.set('view engine', 'jade')
app.use(express.bodyParser())
app.engine('.jade', require('jade').__express)
app.use(express.methodOverride())
app.use(express.cookieParser())
app.use(express.session({ store: new express.session.MemoryStore({reapInterval: 50000 * 10}), secret: 'chubby bunny' }))
app.use(express.static(__dirname + '/public'))
app.use((req, res, next) ->
res.locals.session = req.session
next()
)
app.use(app.router)
)
Just to give a short summary for everyone who has the same problem and got the impression that is was solved changing res.redirect.
It is very important to put your app.use middleware before app.router. See the comments by TJ Holowaychuck, the author of express
https://groups.google.com/d/msg/express-js/72WPl2UKA2Q/dEndrRj6uhgJ
Here is an example using a fresh installation of express v3.0.0rc4
app.js:
app.use(function(req, res, next){
res.locals.variable = "some content";
next();
})
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
index.jade:
extends layout
block content
h1= title
p Welcome to #{title}
p= variable
If you are using express.session() you must call your function AFTER express.session() but BEFORE app.router, inside of app.configure().
app.js
app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session());
// Give Views/Layouts direct access to session data.
app.use(function(req, res, next){
res.locals.session = req.session;
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
index.jade
extends layout
block content
h1= title
p My req.session.var_name is set to #{session.var_name}

How to configure express.js/jade to process html files?

I would like to configure jade engine to handle .html files in my views folder. Here is my currentserver configuration:
app.configure(function(){
var pub_dir = __dirname + '/public';
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({ secret: nconf.get("site:secret") }));
app.use(everyauth.middleware());
app.use(require('less-middleware')({ src: pub_dir, force:true }));
app.use(express.static(pub_dir));
app.use(app.router);
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);
});
https://github.com/visionmedia/express/blob/master/examples/ejs/index.js
app.engine('.html', require('jade').__express);
Make sure you already have jade in your node_modules
npm install --save jade
In express 4.x, you can simply set the view engine to jade.
app.set('view engine', 'jade')

Resources