Though I have read quite a few questions being answered on stackoverflow, I'm still unable to get it to work even after a couple of days of trying. It's my first week with express and node and so I don't know if I'm doing the small things right. I basically want to upload a file and later on save it to the file system, however, I'm unable to proceed with req.files giving me undefined. Please see my code below.
This is my app.js
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var routes = require('./routes/index');
var users = require('./routes/users');
var upload = require('./routes/upload.js');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/upload', upload);
/// 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: {}
});
});
module.exports = app;
This is my routes/upload.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
console.log("");
console.log(req.files);
res.send('this is the page you get upon doing file upload');
});
module.exports = router;
This is my views/homepage.jade
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
p select file to upload
form(action="upload", method="get", enctype="multipart/form-data")
input(type="file", name="displayImage")
input(type="submit")
At the moment, I'm hearing a lot of terms like multer, connect-busboy, bodyParser being deprecated from express4 etc but with no real idea on how to proceed. Please advise me on how I can proceed and what code should be added.
Thanks.
You need a middleware module that can parse your uploaded file.
Like such:
https://github.com/expressjs/multer
https://github.com/mscdex/connect-busboy
Then use the middleware in your index.js, like:
app.use(multer({ dest: './uploads/'}))
or
app.use(busboy());
A number of modules were removed from Express in 4.0 and are now separate packages you have to include. The easiest way to get started with it is to use express-generator to generate the scaffolding for you. This will include and require the correct packages for parsing cookies, and the request body. It doesn't include a file parser however. I put together an example using multer and put it on Github for you to reference.
After you clone it, you can run npm install, and then npm start.
One other thing you were doing incorrectly that I fixed was using app.get for your upload handler. You can't use GET to upload a file. In my example I changed this to a POST request. Here are the relevant snippets.
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var multer = require('multer');
var routes = require('./routes/index');
var users = require('./routes/users');
var upload = require('./routes/upload');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(multer({ dest: './uploads/'}))
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/upload', upload);
// 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: {}
});
});
module.exports = app;
index.jade
extends layout
block content
h1= title
p select file to upload
form(action='upload', method='post', enctype='multipart/form-data')
input(type='file', name='displayImage')
input(type='submit')
Related
I am trying to bind my style into some external CSS that I have in my project directory.
My app structre looks like this:
webDTU
app.js
public/
stylesheets/
style.css
avgrund.css
animate.css
views/
index.jade
UserHome.jade
....
....
my UserHome.jade:
doctype html
html
head
title MQTT Chat Application
script(type='text/javascript', src='http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js')
link(rel='stylesheet', href='http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900,100italic,300italic,400italic,700italic,900italic', type='text/css')
link(rel='stylesheet', href='../public/stylesheets/animate.css', type='text/css')
link(rel='stylesheet', href='../public/stylesheets/style.css', type='text/css')
link(rel='stylesheet', href='../public/stylesheets/avgrund.css', type='text/css')
body
.avgrund-contents
header
h1 hi #{title}
.pr.center.wrapper
.cf.pr.chat.animate
.pa.chat-shadow
.....
my app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/webDTU');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req,res,next){
req.db = db;
next();
});
app.use('/', routes);
// 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: {}
});
});
module.exports = app;
My problem is that somehow href='../public/stylesheets/animate.css' does not load the correct file from my project directory and I do not understand why it does not work.
Then in html use
href='/public/stylesheets/animate.css'
When I run the localhost:3000/users/yu , I get a 404 not found. Why is the post() coming up as undefined? when I run a POST from my iOS app I get a "undefined token" error. I'm running node v5.7.0 and express v4.13.4 Project was generated using express-generator to create Webstorm project.
var express = require('express');
var router = express.Router();
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res) {
res.send("yoma");
});
router.post('/yu', function(req, res) {
var test = req.body;
//parse test
});
My app.js looks like this:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
// 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: {}
});
});
module.exports = app;
when you navigate your browser to localhost:3000/users/yu it makes GET http query, but in your router you have only POST handler for '/yu'
router.post('/yu', function(req, res) {
console.log(req.body);
});
Add GET handler for '/yu' like this for example
router.get('/yu', function(req, res) {
console.log(req.body);
});
After that you should not get a 404 error when navigate to localhost:3000/users/yu
I´m currently trying to render my .ejs-templates with some variables, but I´m kinda stuck and can`t help myself. I´ve installed express over the express-generator with compass and ejs.
In my routes/index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.write('Hello World')
res.end();
});
module.exports = router;
So I want to render <%= name %> in index.ejs (views/index.ejs) with the name Jack. In a few tutorials it should work this way, but it just don`t works for me.
I got an error telling me that the variable name is not defined. Would be very nice, if you guys could tell me, what I´m doing wrong or what I´ve missed.
I´m using ejs the first time and just can`t figure out my mistake =/
This is my app.js server-file
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var http = require("http");
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
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(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('node-compass')({mode: 'expanded'}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
// 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: {}
});
});
module.exports = app;
regards,
Cab
edit: I figured out that the rendering of the variable title works, but all the other variables don`t work. I can imagine, that I can only access some kind of global variables and title is one of them =/
edit2: Found out, that my routing isnt working properly ... so the rendering isnt working ofc. But can`t figure out my mistake =/
If you have split your project up into different modules then you need to export those modules so they are available in other parts of your app.
For example you have separate route modules where you are defining your routes. For these to be available to the rest of your app then you need to make them available using the module.exports command.
so at the end of routes/index.js you need to have
module.exports = router;
The end of the express page on routing gives an example
I am trying to create two separate routes in NodeJS, I am using the express framework and angular on the client side. I am currently able to render my index page successfully by visiting localhost:3000/ although when I try to render the login page by visiting localhost:3000/login I am getting a GET /login 404 error and not sure why b/c I set it up extremely similar to the index route. Not sure if I missed something.
This my app.js
//require dependencies
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//require routes but do not user yet
var routes = require('./routes/index');
var login = require('./routes/login');
//start app
var app = express();
// view engine setup - default views directory
app.set('views', path.join(__dirname, 'views'));
app.locals.delimiters = '<% %>';
app.set('view engine', 'hjs'); //use hogan templating for views
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('less-middleware')(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/login', login);
// 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: {}
});
});
module.exports = app;
routes/login.js
var express = require('express');
var router = express.Router();
router.get('/login', function(req, res){
res.render('login');
});
module.exports = router;
views/login.hjs
<!DOCTYPE html>
<html>
<head>
</head>
<body>
HELLO WORLD
</body>
</html>
Visiting localhost:3000/login renders the following:
{{ message }}
{{ error.status }}
{{ error.stack }}
When writing app.use('/login', login), you are telling Express to use your router under the namespace : '/login'; Therefore, all routes defined into login.js don't need this prefix.
Try to access localhost:3000/login/login ;)
Then, just change your router to:
router.get('/', function(req, res){
res.render('login');
});
I've created a build environment using express JS. But, I got into trouble to configure AngularJS view -- Pleas help me to fix this issue..
1:
var express = require('express');
var http = require('http');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var httpServer = http.createServer(app);
// view engine setup
//app.set('views', path.join(__dirname, 'views'));
//app.set('view engine', 'jade');
//res.render('dist/index.html');
//app.engine('html', require('ejs').renderFile);
//Trying to setup my view over here -- dist folder is holding the index.html file
app.set('views', __dirname + '/dist');
app.set('view engine', 'html');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/dist/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static('./dist'));
app.use('/', routes);
app.use('/users', users);
// 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: {}
});
});
httpServer.listen('8080');
console.log("server is started");
Above build setup was throwing following error ::
Error : Can't find module 'html' -- I'm not sure how to configure Node.Js to refer the angular JS veiw and all the injuctors..
The problem is with this line:
app.set('view engine', 'html');
You are trying to specify view engine with html value, which is not a view engine (expressjs tries to require html module internaly, but doesn't find it). If you need to serve just html files without templating use:
app.use(express.static(__dirname + '/public'));
And move all files you want to serve to public folder.
UPD: you can actually require html file from jade
in views/index.jade
include plain.html
in views/plain.html
<!DOCTYPE html>
...
and app.js can still just render jade:
res.render(index)
Andrew Homeyer's answer
References:
http://expressjs.com/4x/api.html#app.engine
How do I use HTML as the view engine in Express?
http://expressjs.com/guide/using-template-engines.html