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');
Related
I found that if middleware in app.js were in the wrong order , they wouldn't work well.
For example:
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs'); //
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded()); //
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
//the codes below don't work
//set Cookie
app.use(cookieParser());
app.use(session({
secret:setting.cookieSecret,
key: setting.db,
cookie:{maxAge:1000*3600*24*30},
store: new MongoStore({db:setting.db}),
saveUninitialized: true,
resave: true
}) );
//use 'connect-flash'
app.use(flash());
If the code app.use(flash()) isn't moved after app.set('view engine', 'ejs');, the page will show TypeError: Object #<IncomingMessage> has no method 'flash'.
What's more,if I just move app.use(flash()) it creates the error req.flash() requires sessions but the error goes away if I move cookieParse() and session() to follow urlencoded().
Editing the first code example to this no longer creates errors:
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
//changed
app.use(flash());
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
//changed
app.use(cookieParser());
app.use(session({
secret:setting.cookieSecret,
key: setting.db,
cookie:{maxAge:1000*3600*24*30},
store: new MongoStore({db:setting.db}),
saveUninitialized: true,
resave: true
}) );
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
So I want to know :
Is there a mandatory order that the middleware and configuration in app.js must follow?
Yes. The order you call middleware or configuration in Express is important. From the express api docs:
The order of which middleware are "defined" using app.use() is very
important, they are invoked sequentially, thus this defines middleware
precedence.
This is why you get the different errors as you move the different app.use lines around.
For example, if you are using connect-flash for your flash() function, connect-flash requires both cookieparser and session middleware to be loaded first. There is an order dependency -- cookieparser, then session, then flash.
Order is also important for routing. See the New features in Express 4.x and this stackoverflow answer for details and discussion.
Therefore, when using express, check the documentation to be sure you meet order-based dependencies for middleware and routes (when applicable).
Is there any specific order in which these three commands should be written in the app.configure function?
app.use(express.urlencoded());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
I am asking this because when I change their order , I sometimes get an ENOENT error or some middleware doesn't work.
So in the default app.js file express creates the order is
app.use(express.bodyParser()); // or app.use(express.urlencoded())
app.use(app.router);
app.use(express.static(__dirname + "/public"));
So I guess this is the right way...
I really apologize if I'm leaving something out and am totally stupid, but I've checked and checked over again a number of times, and the file upload functionality is just not working over here. I made a super minimal app to demonstate. Just generated a new express app with the most up-to-date version (3.4.7) and added the least i could to make a file upload work.
Here's my app.js file
/**
* Module dependencies.
*/
var express = require('express');
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.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('/tasks', function(req, res) {
res.render('form');
});
app.post('/tasks', function(req, res) {
console.log(req.files);
res.send('ok');
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
exports = module.exports = app;
And here's my form.jade view file:
doctype html
html
head
title Task Upload
body
form(action='/tasks', method='post', enctype='multipart/form-data')
input(name='task', type='file')
input(type='submit')
Everytime I try to upload a file, req.files logs out undefined. Can anyone save me out from this problem?
Add the following in your app.js
app.configure(function(){
app.use(express.methodOverride());
app.use(express.bodyParser({keepExtensions:true,uploadDir:path.join(__dirname,'/files'}));
});
And then try to access as follows;
req.files.task
It is recommended not to use bodyParser, but to simply define the type of handling you want. In your case since its file uploading, you can enable it as follows
app.configure(function(){
app.use(express.methodOverride());
app.use(express.multipart());
});
You can read about why using bodyParser() is not a good idea in the following link.
http://andrewkelley.me/post/do-not-use-bodyparser-with-express-js.html
In Express 4, req.files is no longer available on the req object by default.
To access uploaded files on the req.files object, use multipart-handling middleware like busboy, multer, formidable, multiparty, connect-multiparty,.
I'm trying to set some response-specific variables, and I'm getting undefined for res.locals when I log it from within my middleware, but it returns the function just fine if I log it from within a route function.
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(function (res, req, next) {
console.log("res.locals from app.use middleware: ", res.locals);
// res.locals.boom = 'nice';
// res.locals.zoom = 'yeah!';
next();
});
app.use(app.router);
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
Any ideas?
You have your request & response objects backwards. Obviously if you know the difference in your code, naming doesn't matter, but best to keep things named correctly.
app.use( function (request, response, next) {
// stuff
});
I can't recall off the top of my head, but I believe you want:
request.app.locals;
using my example above. Again, not 100% sure. You can always console out the request object to check.
The app.locals object is a JavaScript Function, which when invoked with an object will merge properties into itself, providing a simple way to expose existing objects as local variables.
app.locals({
title: 'My App',
phone: '1-250-858-9990',
email: 'me#myapp.com'
});
app.locals.title
// => 'My App'
app.locals.email
// => 'me#myapp.com'
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.