I'm trying to serve a home view using Express/Angular, such that when the root url ('/') is accessed, a view is loaded. Right now navigating to http://localhost:3000 displays an empty page with <!-- ngView: --> and nothing else. Navigating to http://localhost:3000/about displays the about page as expected. How do I get the home partial to display when the root is accessed?
app.js (w/ Express 4.9.0)
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var routes = require('./routes');
var path = path = require('path');
app.set('port', process.env.PORT || 3000);
app.use(express.static(path.join(__dirname, 'public')));
server.listen(app.get('port'), function() {
console.log('Listening on port ' + app.get('port'));
});
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.get('/', routes.index);
app.get('/partials/:name', routes.partials);
app.get('*', routes.index);
routes/routes.js
exports.index = function(req, res){
res.render('index');
};
exports.partials = function (req, res) {
var name = req.params.name;
res.render('partials/' + name);
};
views/index.jade
doctype
html(ng-app="myApp")
head
meta(charset='utf8')
base(href='/')
title Angular Express Seed App
link(rel='stylesheet', href='/css/app.css')
body
div(ng-controller='AppCtrl')
div(ng-view)
script(src='bower_components/angular-loader/angular-loader.js')
script(src='bower_components/angular/angular.js')
script(src='bower_components/angular-route/angular-route.js')
script(src='bower_components/socket.io-client/socket.io.js')
script(src='js/app.js')
script(src='js/main.js')
script(src='js/services.js')
script(src='js/controllers.js')
script(src='js/filters.js')
script(src='js/directives.js')
public/js/app.js
angular.module('myApp', [
'myApp.controllers',
'myApp.filters',
'myApp.services',
'myApp.directives',
'ngRoute'
]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateURL: 'partials/home',
controller: 'MyCtrl2'
}).
when('/about', {
templateUrl: 'partials/about',
controller: 'MyCtrl1'
}).
otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
});
I also have a views/partials/home.jade and a views/partials/about.jade
I think you may have misspelled templateUrl in
when('/', {
templateURL: 'partials/home',
controller: 'MyCtrl2'
}).
Related
router.get('/dist/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
my app.js routing code
app.set('dist', path.join(__dirname, 'dist'));
app.set('view engine', 'html');
app.engine('html', require('hbs').__express);
my folder structure
root/dist/index.html
I cannot open this page on my first page
how can I open this page? Where is my mistake?
thank you for your help
You can use the method set() to redefine express's default settings.
app.set('views', path.join(__dirname, '/dist'));
Working Example
const express = require('express')
const path = require('path')
const app = express()
const port = 3000;
var indexRouter = require('./routes/index');
// Set 'views' directory for any views
// being rendered res.render()
app.set('views', path.join(__dirname, '/dist'));
// Set view engine
app.engine('html', require('hbs').__express);
app.set('view engine', 'html');
app.use('/', indexRouter);
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
routes/index.js
var express = require('express');
var router = express.Router();
router.get('/dist/', function(req, res, next) {
res.render('index', { title: 'Inside Dist Folder Index' });
});
module.exports = router;
I'm having a problem routing in express 4. I was following the example, but it isn't loading. I'm just getting a spinning wheel.
How do you do routing in express version 4?
app.js:
var express = require('express');
var http = require('http');
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
var port = (process.env.PORT || process.env.VCAP_APP_PORT || 5000);
app.use('/birds', require('./controller/bird'));
http.createServer(function (req, res) {
//res.writeHead(200, {'Content-Type': 'text/plain'});
//res.end('Hello World!\n');
}).listen(port);
console.log('Server running at http://127.0.0.1:'+port);
bird.js:
var express = require('express');
var router = express.Router();
// middleware specific to this router
router.use(function timeLog(req, res, next) {
console.log('Time: ', Date.now());
next();
});
// define the home page route
router.get('/', function(req, res) {
res.send('Birds home page');
});
// define the about route
router.get('/about', function(req, res) {
res.send('About birds');
});
module.exports = router;
You're not calling the app.listen() function. Instead of the http.createServer one, you should invoke the Express function.
Please, take a look at a basic example.
Relevant code:
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Edit: as slebetman wrote in the comment, the more general way for it is:
http.createServer(app).listen(port, function(){
console.log('now listening on port ' + port);
});
I am using Node.js + Express + Jade to demo some very simple pages. I got this problem for two days. I googled a lot, but cannot find answer. Basically, I redirect from a page to another. And on the target page, I have some socket.io code inside document.ready. The problem is from /pageone, the pagetwo is rendered correctly(but url in browser is still /pageone), but the code inside document.ready is not executed.
My router.js
app.post('/pageone', session, function(req, res){
res.redirect('/pagetwo');
});
app.get('/pagetwo', function(req, res){
res.render('pagetwo', { title: 'demo' });
});
My pagetwo jade
doctype
html
head
title #{title} - My Site
link(rel='stylesheet', href='/css/style.css')
script(type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js')
script(type='text/javascript' src='https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js')
script.
$(document).ready(function() {
alert("I am an alert box!");
});
body
h1 DEMO
The result is that I can see DEMO on the page but alert box is not showing. But if I directly visit /pagetwo, the alert box is showing.
Many thanks
////// EDITED //////
This is my app.js
var express = require('express')
, http = require('http')
, session = require('express-session');
var app = express();
var port = process.env.PORT || 8080;
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('port', port);
app.use(express.static(__dirname + '/public'));
app.use(session({ secret: 'gdfgsdrgesrgerge', cookie: { maxAge: 60000 }}))
require('./controller/router')(app);
var server = http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
})
And this is my router.js
var express = require('express');
module.exports = function(app) {
app.get('/pageone', function(req, res){
res.render('pageone', { title: 'Welcome' });
});
app.post('/pageone', function(req, res){
res.redirect('/pagetwo');
});
app.get('/pagetwo', function(req, res){
res.render('pagetwo', { title: 'demo' });
});
};
I am working on a single page web app with node/angular and jade. I am fairly new to angular, and I wanted to know what I have to do with my app.js file so that my first page template loads from my angular file rather than from my jade template.
I structured my files as such:
public/
index.html
javascript/
img/
stylesheets/
routes/
index.js
views/
partials/
a.jade
b.jade
app.js
This is what my app.js looks like:
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.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')));
app.use(express.cookieParser('cookies monster')); // Cookie secret
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
/*
* Views
*/
app.get('/', routes.index);
app.get('/a', routes.a);
app.get('/b', routes.b);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
My index.js looks like this:
exports.index = function(req, res){
res.render('index', { title: 'Test Application' });
};
// View A
exports.a = function(req, res) {
res.render('partials/a', { layout: false, test: 'LOL' });
};
// View B
exports.b = function(req, res) {
res.render('partials/b', { layout: false, test: 'YOLO' });
};
When I run this, It does not use the index.html as the first page. How would I go about doing so, so that the initial page template is actually the index.html? I can't seem to find the answer anywhere.
You could return the actual index.html file from your router.
app.get('/', function(req, res, next){
return res.sendfile(app.get('public') + '/index.html');
});
I should note that I also put app.set('public', path.join(__dirname, 'public')); inside app.js for easy access to the public directory.
I have the root route and it works fine. I also have a another route 127.0.0.1:3000/dashboard if I just type that url into the address bar I get this error:
Cannot GET /dashboard
If I create a link to the same url it works fine.
If I then refresh that page I get the same error again.
Below is my node.js route
app.js
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, stats = require('./routes/stats')
, tests = require('./routes/test')
, http = require('http')
, util = require('util')
, path = require('path');
var app = module.exports = express();
app.configure(function(){
/*
* Configuration
*
*/
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
/*
* Middleware definitions
*
*/
app.use(express.favicon());
app.use(express.logger('dev'));
/*
* Error handling middleware
*/
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('shhhhhhhh, super secret'));
app.use(app.router);
// serves up dynamic css files
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(require('less-middleware')({ src: __dirname + '/public' }));
// serves a static path
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
/*
* Endpoints
*/
app.get('/', routes.index);
app.get('/test', tests.get);
app.post('/test', tests.post);
app.options('/test', tests.options);
app.get('/stats/sends', stats.sends.get);
app.get('/stats/events', stats.events.get);
app.get('/stats/attempts', stats.attempts.get);
app.get('/stats/errors', stats.errors.get);
app.get('/stats/mquad', stats.mquad.get);
app.get('/partials/:name', routes.partials);
app.get('/index/landing', routes.landing);
app.get('/index/dashboard', routes.dashboard);
console.log('Env: ' + app.settings.env);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
routes/index.js
exports.dashboard = function(req, res){
res.render('dashboard');
};
Angular route
'use strict';
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives']).
config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/landing',
controller: LandingCtrl
}).
when('/dashboard', {
templateUrl: 'partials/dashboard',
controller: DashboardCtrl
}).
otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
}]);
The reason this does not work is that your server is not catching all other routes and routing them to your single page app which is served by routes.index.
In order to catch all other routes and route them to the index page so that your angular app can see if it matches the supplied url all you need to do is add the following line after your last route is declared:
app.get('*', routes.index);
Now you should be able to:
navigate directly to a url served by your Angular.js app
refresh any page without error
This article might help:
http://jjt.io/2013/11/16/angular-html5mode-using-yeoman-generator-angular/
In a nutshell:
npm install --save-dev connect-modrewrite
Gruntfile:
connect: {
options: {
// ...
// Modrewrite rule, connect.static(path) for each path in target's base
middleware: function (connect, options) {
var optBase = (typeof options.base === 'string') ? [options.base] : options.base;
return [require('connect-modrewrite')(['!(\\..+)$ / [L]'])].concat(
optBase.map(function(path){ return connect.static(path); }));
}
}
}
Route app.get('/index/dashboard', routes.dashboard); refers to http://hostname/index/dashboard whereas when('/dashboard', { ... }) refers to http://hostname/dashboard.
You should correct the route: app.get('/dashboard', routes.dashboard);
I'd suggest a pretty fast javascript solution in front and back end.
NodeJs
// set up our one route to the index.html file
app.get('*', function (req, res){
res.sendFile(path.join(__dirname+'/public/index.html'));
});
This code tells to de local/remote server where is the main html, so it could find the rest of templates.
AngularJs
// If 404 Redirect to home
$routeProvider.otherwise( { redirectTo: '/'} );
This is also really helpful, so never goes to a missing page.