Struck with routing issue in expressjs and AngularJs project.
It's not a single page application and I am not using any view engines such as jade.
We are just using plain HTML.
I am working on password reset functionality where user can reset the password by clicking a link provided by an email. So I assume there won't be any route change event in the context of Angular (Please correct me if I am wrong).
And my express configurations are as follows.
routes = require('./routes/index');
app.configure(function () {
app.use(express.static(__dirname + '/app'));
app.use('/css', express.static(__dirname + '/app/css'));
app.set('views', __dirname + '/app');
app.set("view options", { layout: false });
app.engine('.html', require('ejs').__express);
app.set('view engine', 'html');
app.use(express.favicon());
//app.use(require('connect').bodyParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
});
// Routes
app.get('/', routes.index);
app.get('/resetpassword.html/:resetcode', function (req, res) {
console.log("reset code: " + req.params.resetcode);
res.render('resetpassword.html/' + req.params.resetcode);
});
app.get('/api', function (req, res) {
res.send('Ecomm API is running');
});
// JSON API
app.post('/registeruser', usersApi.registerUser);
app.post('/api/login', usersApi.logIn);
app.post('/api/addgame', gamesApi.addGame);
app.get('*', routes.index);
// Start server
app.listen(2221, function () {
console.log("Express server listening on port %d in %s mode", 2221, app.settings.env);
});
and index.js
exports.index = function(req, res){
res.render('home.html');
}; // Always rending index.html which needs to be fixed.
And app.js from AnghularJs as follows
app.config(function ($routeProvider) {
$routeProvider
.when('/', { templateUrl: 'home.html' })
.when('/resetpassword.html/:resetcode', { templateUrl: '/resetpassword.html', controller: 'ResetPasswordCtrl' })
.otherwise({ redirectTo: '/' });
});
I am getting 500 internal error or view not found error.
Any suggestions please.
You are concatenating the password to the view name that you pass to render hence why Express does not find the view and returns a 500 error. You need to pass the data as an additional parameter to the render function as an object:
res.render('resetpassword.html', {resetcode: req.params.resetcode} );
Then in your view use resetcode directly e.g.
<span><%= resetcode %></span>
Related
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 am using the book "Smashing Node.js" by Guillermo Rauch. Chap. 12 sets up some views/routes before an authentication example. I have followed the tutorial to the best of my ability and searched (and searched) for my error.
//package.json
{
"name": "login"
,"version":"0.0.1"
,"main":"./index"
,"dependencies": {
"express": "3.0.0"
,"uglify-js" : "2.4.0"
,"mongodb":"1.3.19"
,"mongoose":"3.6.20"
,"bcrypt":"0.7.7"
,"jade":"0.35.0"
}
}
here is my index.js
/**module dependenies**/
var express = require('express')
, mongodb = require('mongodb');
//set up app
app = express();
//middleware
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'my secret'}));
//view options
app.set('view engine', 'jade');
//app.set('views', __dirname + '/views');
//app.set('view options', {layout: false});
//routes
//default route
app.get('/', function (req, res){
console.log('default');
res.render('index', {authenticated: false});
});
//login route
app.get('/login', function (req, res){
console.log('login');
res.render('login');
});
//signup route
app.get('/signup', function(req, res){
console.log('signup');
res.render('signup');
});
//listen
app.listen(3000);
in the same directory I have a folder of views/layout.jade, index.jade, signup.jade, login.jade I will show two.
'layout.jade'
doctype 5
html
head
title BN Login
body
.wrapper
block body
and index.jade
extends layout
block body
if (authenticated)
p Welcome back, #{me.first}
a(href="/logout") Logout
else
p Welcome visitor!
ul
li: a(href='/login') Login
li: a(href="/signup") Signup
the lines I have commented out did not help or are old.
The layout.jade renders. The console shows that the code is being read. No other view is rendered.
Thanks.
I think you have not used indentation correctly. In your index this :
extends layout
block body
if (authenticated)
...
else
should be :
extends layout
block body
if (authenticated)
...
else
I'd like to set up some subdomains for my Node.js app. I've built my site with express.js, and now I'd just like to throw up a little web tool on a subdomain of my site. I've tried using the vhost middleware with little luck, but am open to other approaches.
Any help would rock!
Ideally, I could just drop a new express app in a sub directory change a few lines of code, maybe change some DNS settings at it would work. The reason I'd like this is so that I can reuse a fresh instance of stylus and jade with new layouts and css styles and so forth.
Here's my normal app.js, the commented line is the attempt to use vhost.
var express = require('express'),
routes = require('./routes');
var app = module.exports = express.createServer();
// Configuration
app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('view options', { layout: false });
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use('/courses', function (req, res, next) {
var privates = require('./.private.json'),
couch = require('nano')('https://' + privates.dbCreds.username + ':' + privates.dbCreds.password + '#wamoyo.iriscouch.com/');
});
app.use(require('stylus').middleware({
src: __dirname + '/public'
}));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
// VHOST - SUBDOMAIN
// app.use(express.vhost('adventures.innovationbound.com', require('./adventures/index').app));
app.use(function (req, res, next) {
res.status(404);
res.render('four', {
title: "Innovation Bound",
now: new Date().getFullYear()
});
});
app.use(function (err, req, res, next){
console.error(err.stack);
res.send(500, 'Something broke!');
});
});
app.configure('development', function() {
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
});
app.configure('production', function() {
app.use(express.errorHandler());
});
// Routes
app.get('/', routes.index);
app.get('/about', routes.about);
app.get('/services', routes.services);
app.get('/events', routes.events);
app.get('/blog', routes.blog);
app.post('/contact', routes.contact);
// Courses
// app.get('/heartbeat', routes.heartbeat);
app.get('/courses', routes.courses);
// Tools
app.get('/point', routes.point);
app.listen(3000, function() {
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});
This is using express 2.5, I wouldn't mind migrating over to 3 if need be.
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.