It's probably a newbie question. I'm trying to setup my very first expressjs application and I need to use a view helpers that doesn't work for some reason.
Here is my server.js
var express = require('express');
var app = express();
var test = function(req, res, next) {
res.myLog = function(){
console.log("res");
return "Hello";
}
next();
}
app.use(test);
app.get("*", function(req, res) {
res.sendfile('./dist/index.html');
})
app.listen(5000);
And index.html
<html>
<head>
<title>Test application</title>
<link rel="stylesheet" href="main.css" />
<script src='<%=myLog()%>'></script>
</head>
<body>
<h1>Yo World!</h1>
</body>
</html>
myLog function is not call during rendering. Originally I was trying to use some third part helpers and they didn't work as well.
I haven't found any documentation of how to use the helpers on expressjs site. I'm clearly doing something wrong here.
Express version 4.3.14
To send file using express, correct ways is:
//sending html files
var express = require('express');
var app = express();
var path = require('path');
// viewed at http://localhost:5000
app.get('/', showClientRequest, function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
function showClientRequest(req, res, next) {
var request = {
REQUEST : {
HEADERS: req.headers,
BODY : req.body
}
}
console.log(request)
return next();
}
app.listen(5000);
Use ejs template engine:
var express = require('express');
var ejs = require('ejs');
var app = express();
app.set('view engine', 'ejs');
var path = require('path');
// viewed at http://localhost:5000
app.get('/', showClientRequest, function(req, res) {
res.render('index',{message:"Hello World!"});
});
function showClientRequest(req, res, next) {
console.log('Something Here...');
return next();
}
app.listen(5000);
Node-Cheat Available:
For complete code, get working node-cheat at express_server run node app followed by npm install express ejs.
Use res.locals.myLog instead of res.myLog to set locals. If you don't need req within your helper function you can also use app.locals.myLog.
res.sendfile will not render your view but just send a file as it is. You will have to use res.render and move your dist/index.html to views/index.ejs.
Related
I'm trying to implement uppy the file upload program into my website, but when i try to include it, I get an error message saying that document is not defined. This is already me using browserify to include it on my client side. However, I'm not sure what I'm doing wrong. Any help will be appreciate it. My code is below. FYI, I used IntelliJ Idea by Jet Brains as my IDE, and I had the IDE generate my node js project, so it automatically created me some pages with routing included.
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
require('./uppy');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
uppy.js(this is where I placed the uppy code from the documentation)
// Import the plugins
const Uppy = require('#uppy/core');
const XHRUpload = require('#uppy/xhr-upload');
const Dashboard = require('#uppy/dashboard');
const uppy = Uppy()
.use(Dashboard, {
target: '#drag-drop-area',
inline: true
})
.use(XHRUpload, { endpoint: 'https://api2.transloadit.com' });
uppy.on('complete', (result) => {
console.log('Upload complete! We’ve uploaded these files:', result.successful)
});
index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href="../node_modules/#uppy/core/dist/style.css" />
<link rel='stylesheet' href="../node_modules/#uppy/dashboard/dist/style.css" />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<div id="drag-drop-area"></div>
<script src="../bundle.js"></script>
</body>
</html>
As you can see, I used bundle.js to incorporate the code from uppy.js by using browserify. I used the cli browserify uppy.js -o bundle.js. I honestly don't know what I'm doing wrong, so if you can help me with this, I really appreciate it. Thank you!
UPDATE: On my console I am also getting the errors:
http://localhost:3000/node_modules/#uppy/core/dist/style.css (net::ERR_ABORTED 404 (Not Found))
http://localhost:3000/node_modules/#uppy/dashboard/dist/style.css (net::ERR_ABORTED 404 (Not Found))
http://localhost:3000/bundle.js (net::ERR_ABORTED 404 (Not Found))
I am 100% just guessing here because I can't see the full code/repo and full stacktrace of the error but it sounds like you're referencing document in Node.js code and that's what is throwing this error. document is something that lives in the browser DOM and can only be referenced by UI code. It's important to understand the difference between your Node/Express code which is the backend server and your presentation/UI code which is what gets rendered in the browser.
I am trying to create and start a server and I've been looking at other code and can't see why mine isn't working (just getting this: localhost just keeps loading and loading and nothing happens).
Any ideas? Thanks!!!
app/server/app.js :
'use strict'
var express= require ('express');
var path=require('path');
var bodyParser = require('body-parser');
var http = require('http');
var app= express();
module.exports = app;
app.use(express.static(path.join(__dirname, '../browser')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var server = http.createServer();
server.listen(1337, function () {
console.log('Server is listening on port 1337!');
});
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(500).send(err.message);
});
app/browser/index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<title>node</title>
</head>
<body>
<div>
<p>Hey whats up</p>
</div>
</body>
</html>
Your code works for me.
The only thing wrong in your code is you have to change server.listen(1337, function ()..., to app.listen(1337, function () {...
Also, I added a file path...
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, '/index.html'));})
...to link your localhost:1337 to your index.html file. Now your index.html file will display when you go to localhost:1337.
Lastly, I'm not sure if you need this line... var server = http.createServer();. I deleted it and everything worked fine.
Here's the code below.
'use strict'
var express= require ('express');
var path=require('path');
var bodyParser = require('body-parser');
var http = require('http');
var app= express();
module.exports = app;
app.use(express.static(path.join(__dirname, '../browser')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, '/index.html'));
})
app.listen(1337, function () {
console.log('Server is listening on port 1337!');
});
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(500).send(err.message);
});
Maybe the port You wrote - 1337 is busy, check by choosing other port, for example 4200, or 3000 - server.listen(4200,function () {
I want to use router functionality of node to call server side methods. I am not using express generator to generate project structure.
I made some changes to the code in the answer by Mukesh Sharma and made it work:
Server.js (Server code)
var express = require('express');
var app = express();
var routes = require('./FirstAppServer/route');
app.use('/', routes);
// //set static folder
app.use(express.static('FirstApp/public'));
app.use('/module', express.static('node_modules'));
app.listen(3000, function () {
console.log('Port 3000');
});
app.get('/', function (req, res) {
res.redirect('login.html');
});
module.exports = app;
route.js
var express = require('express');
var router = express.Router();
router.post('/endpoint', function (req, res, next) {
console.log('Server side call');
next();
});
module.exports = router;
test.html
<!doctype html>
<html>
<head>
<title>Login</title>
<script src="js/jquery-3.1.0.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
testServerCall();
});
function testServerCall(){
debugger;
$.ajax({
type:"post",
url:"/endpoint",
data:{
"a":"a"
},
success:function(){
console.log('success');
},
error:function(){
console.log('error');
}
});
}
</script>
</head>
<body>
<div id="divLogin">
<input type="text" id="txtUsername" />
</div>
<h2>Login</h2>
Create User
</body>
</html>
You can define routes in different file and can import in the server.js .
server.js - Server code
var express =require('express');
var apis = require('./api.js');
var app = express();
app.use('/api', apis);
app.listen(3000);
api.js - Api router
var express =require('express');
var router = express.Router();
router.get('/users', function (req, res) {
return res.json([{
name: 'John Doe',
email: 'john#doe.com'
}]);
});
module.exports = router;
Hope it helps you.
I have a simple express app (version 4.9.0) and I am trying to put my middleware in to external files.
My app.js has:
var middleware = require('./lib/middleware');
app.get('/foo', middleware.configcache);
/lib/middleware contains index.js:
exports.configcache = require('./configcache.js');
/lib/middleware/configcache.js contains:
function configcache(req, res, next) {
console.log("hello world");
next();
}
module.exports = configcache;
When I make a GET request to /foo I get a 404. Can anyone advise?
This is how I use it in one of my apps:
app.js:
var routes = require('./routes/index');
routes/index.js:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', {
title: req.i18n.t("meta.title.index")
});
});
module.exports = router;
I scaffolded this express project with the yeoman express generator: yo express
So the answer to your problem is: Don't call next(), but send an actual response to the browser - when you are using router.get():
function configcache(req, res, next) {
res.send(200, 'hello world');
}
or use router.use like described here: http://expressjs.com/guide/using-middleware.html
I'm trying to add a new route in my express app but I keep getting error when trying to start the server. The error is
C:\development\node\express_app\node_modules\express\lib\router\index.js:252
throw new Error(msg);
^
Error: .get() requires callback functions but got a [object Undefined]
here are my files, I'm new to node so let me know if i left out an important file
routes/furniture.js
exports.furniture = function(req, res){
res.render('furniture', { title: '4\267pli' });
};
routes/index.js
/*
* GET home page.
*/
exports.index = function(req, res){
res.render('index', { title: '4\267pli' });
};
views/furniture.ejs
<!DOCTYPE html>
<html>
<head>
<title>4·pli -- architecture</title>
<link rel='stylesheet' href='/stylesheets/style.css'/>
<link href='http://fonts.googleapis.com/css?family=Didact+Gothic' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="wrapper">
<h1 class="logo"><%= title %></h1>
</div>
</body>
</html>
app.js
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, furniture = require('./routes/furniture')
, http = require('http')
, path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public'));
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('/furniture', routes.furniture);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
The trouble is:
routes = require('./routes'),
user = require('./routes/user'),
furniture = require('./routes/furniture'),
These 3 are setting your routes folders, not a specific file, express will look for a index.js ( not found, then --> error)
Inside these folders, you should put a index.js with your:
exports.xxxx = function(req, res){
res.render('xx', { foo: foo});
};
Then, your project folder structure should look like:
routes/
├── index.js
│
├── user/
│ └── index.js (with a exports.user inside)
│
└── fourniture/
└── index.js (with a exports.furniture inside)
You can add multiple export functions to a route like these:
app.js
// a folder called routes with the index.js file inside
routes = require('./routes')
.
.
.
app.get('/', routes.main_function);
app.get('/sec_route', routes.sec_function);
app.post('/other_route', routes.other_function);
/routes/index.js
exports.main_function = function(req, res){
res.render('template1', { foo: foo });
};
exports.sec_function = function(req, res){
res.render('template2', { bar: bar });
};
exports.other_function = function(req, res){
res.render('template1', { baz: baz });
};
If your website is so big some times I prefer to do something like:
routes/furniture.js:
module.exports = function(app)
{
app.get("/furniture/", function(req, res) {
res.render('furniture', { title: '4\267plieee' });
});
}
And then in app.js:
require("./routes/furniture")(app);
It's mainly the same but app.js will be cleaner.
Although this is somewhat old, though of sharing the way i do this. Here is a another approach which makes code more cleaner and easy to add routes.
app.js
const app = express();
const routes = require('./routes');
app.use('/api', routes); //Main entry point
/routes/index.js
const router = require('express').Router();
const user = require('./user');
const admin = require('./admin');
//This is a simple route
router.get('/health-check', (req, res) =>
res.send('OK')
);
router.route('/users')
.post(validate, user.createUser);
router.route('/users/:userId')
.get(validateUser, user.getUser)
.patch(validateUser, user.updateUser)
.delete(validateUser, user.deleteUser);
router.route('/admins/:adminId/dashboard')
.get(validateAdmin,admin.getDashboard);
module.exports = router;
'validateUser' and 'validateAdmin' are custom middle wares, which will be used to validates request parameters or to do some pre-processing before request reach the actual request handler. This is optional and you can have multiple middleware (comma separated) as well.
/routes/user.js
module.exports = {
createUser:function(req,res,next){
},
updateUser:function(req,res,next){
},
deleteUser:function(req,res,next){
}
}
/routes/admin.js
module.exports = {
getDashboard:function(req,res,next){
}
}
Follow a simple and consistent folder structure, then use a module to have everything done automatically.
Then never look back. Spend time saved on the rest of the important stuff.
TL;DR
$ npm install express-routemagic --save
const magic = require('express-routemagic')
magic.use(app, __dirname, '[your route directory]')
That's it!
More info:
How you would do this? Let's start with file structuring:
project_folder
|--- routes
| |--- nested-folder
| | |--- index.js
| |--- a-file-that-doesnt-share-same-name-with-another-folder.js
| |--- index.js
|--- app.js
In app.js
const express = require('express')
const app = express()
const magic = require('express-routemagic')
magic.use(app, __dirname, 'routes')
In any of your routing files:
For e.g., index.js
const router = require('express').Router()
router.get('/', (req, res) => { ... })
router.get('/something-else', (req, res) => { ... })
Or a-file-that-doesnt-share-same-name-with-another-folder.js
Usually you might want to start a folder and use the index.js
pattern. But if it's a small file it's okay.
const router = require('express').Router()
const dir = 'a-file-that-do-not-have-another-folder-with-same-name' // you can use this to shorten, but it's optional.
router.get(`$(dir)/`, (req, res) => { ... })
router.get(`$(dir)/nested-route`, (req, res) => { ... })
Disclaimer: I wrote the package. But really it's long-overdue, it reached my limit to wait for someone to write it.