I'm using node.js, express and angular.js to make a personal blog. There is a link on the index page: Home. (It's in the layout.jade file as follows)
Everything is fine when I loaded the index page using the address http://localhost:8000/, ng-view loaded my contents correctly. But when I clicked the Home link, all the contents in ng-view just disappeared, I've been digging for a long time, but still couldn't figure out why.
My codes are as follows.
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 routes = require('./routes/index');
var api = require('./routes/api');
var fs = require('fs');
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('/', routes);
app.use('/api', api);
app.get('/partials/:name', function (req, res) {
var name = req.params.name;
//res.render('partials/' + name);
res.render('partials/' + name);
});
// 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/index.js (this is express routes, not angular.js)
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'My Blog' });
});
module.exports = router;
routes.js (angular.js)
angular.module('blogApp', ['ngRoute']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/index',
controller: IndexCtrl
});
}]);
index.jade
extends layout
block content
#main
#content
.ng-view
#side
...(omitted)
block scripts
link(rel='stylesheet', type='text/css', href='/stylesheets/index.css')
layout.jade
doctype html
html(ng-app='blogApp')
head
title=title
base(href='/')
link(rel='stylesheet', type='text/css', href='/stylesheets/vendors/bootstrap.min.css')
link(rel='stylesheet', type='text/css', href='/stylesheets/vendors/bootstrap-theme.css')
link(rel='stylesheet', type='text/css', href='/stylesheets/layout.css')
script(src='/javascripts/vendors/jquery-1.11.3.min.js')
script(src='/javascripts/vendors/jquery.form.js')
script(src='/javascripts/vendors/angular.js')
script(src='/javascripts/vendors/angular-route.js')
script(src='/javascripts/vendors/bootstrap.js')
script(src='/javascripts/vendors/satellizer.js')
script(src='/javascripts/views/login.js')
script(src='/javascripts/angular/controllers.js')
script(src='/javascripts/angular/routes.js')
body
#container
hgroup.header
h1 My Blog
#menu
ul
li
a(href='/') Home //Here is the link
li.nav-login
a(href='login') Login
block content
block scripts
You could try replacing the href attribute from the element with ng-href.
Home
to
<a ng-href="#/"> Home </a>
I think this will fix your problem.
and if you still having the same problem you could do a trick to make it possible by changing your routes.js as follows,
angular.module('blogApp', ['ngRoute']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/index',
controller: IndexCtrl
})
.otherwise('/');
}]);
then try with any link in href ;)
Match your href for your home link to your actual local host url.
` Home
Related
I'm working on my side structure and tried to add multiple single pages.
Here is my site structure:
bin
node_modules
public
query
routes
- index.js
views
-menu
--menu1.ejs
--menu2.ejs
--menu3.ejs
-partials
--header.ejs
-index.js
-anzeige.js
-eintragen.js
I tried to route the sites in my index.js like this:
//works
router.get('/', (req, res) => {
console.log('Request for index recieved');
res.render('index');
});
//works
router.get('/menu1', (req, res) => {
console.log('Request for menu1 page recieved');
res.render('menu/menu1');
});
//not working
router.get('/menu2', (req, res) => {
console.log('Request for menu2 page recieved');
res.render('menu/menu2');
});
//not working
router.get('/menu3', (req, res) => {
console.log('Request for menu3 page recieved');
res.render('menu/menu3');
});
//works
router.get('/anzeige', (req, res) => {
console.log('Request for anzeige page recieved');
res.render('anzeige');
});
I also added index.js to my app.js as a route but somehow my console says me that menu2 and menu3 can't be found (error 500 internal server error).
Request for menu2 page recieved
GET /menu2 500 7.958 ms - 305
GET http://localhost:3000/menu2 500 (Internal Server Error)
Additionally my app.js, which first creates const routes and implents it afterwards with app.use('/', routes);
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
//Place routes here
//var indexRouter = require('./routes/index');
const routes = require('./routes');
var app = express();
// 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')));
//add routes here
app.use('/', routes);
// 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;
menu2.ejs
<!DOCTYPE html>
<html lang="de">
<head>
<title>Speiseplan anzeige</title>
<%- include('partials/header') %>
</head>
<body class="mainContainer">
<div class="midContainer">
<h1>menu2</h1>
</div>
</body>
</html>
Am I missing something? It's a bit strange that some sites work and some not.
Problem found - here the soultion for everyone with the some problem.
As Rajan mentioned I should use ../partials/header instead of partials/header.
This worked for me and everything is now displayed perfectly.
Thank you all!
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'
I am new to angular and I am following the tutorial on angularjs website
What I tried so far:
Installed angular-route and inject the script below angular.min.js
used ngRoute in my module
added the controllers script to my layout.jade
used another view engine, vash, still the same error
included scripts in head, end of body, in layout view, in index.jade nothing works
I am trying to solve this error for two days now. Please help me :(
Here is my code:
layout.jade:
doctype html
html(ng-app="phoneCatApp")
head
meta(charset="utf-8")
script(src='lib/angular/angular.min.js')
script(src='lib/angular-route/angular-route.min.js')
script(src='js/controllers.js')
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body(ng-controller="PhoneListCtrl")
block content
index.jade:
extends layout
block content
ul
li(ng-repeat="phone in phones")
span {{phone.name}}
p {{phone.snıppet}}
controller.js:
var phonecatApp = angular.module('phonecatApp', ['ngRoute']);
phonecatApp.controller('PhoneListCtrl', function ($scope) {
$scope.phones = [
{
'name': 'Nexus S',
'snippet': 'Fast just got faster with Nexus S.'
},
{
'name': 'Motorola XOOM™ with Wi-Fi',
'snippet': 'The Next, Next Generation tablet.'
},
{
'name': 'MOTOROLA XOOM™',
'snippet': 'The Next, Next Generation tablet.'
}
];
});
index.js:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function (req, res) {
res.render('index', { title: 'Express' });
});
module.exports = router;
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 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(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
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;
edit:
I found the problem. when I insert '/' beginning of the script includes the problem was solved. It was because the path should be absolute in order to find scripts even from subdirectories. Thank you all.
What I have understood is your module name is mismatched. Make it correct everywhere (Case-sensitive).
var phonecatApp = angular.module('phonecatApp', ['ngRoute']); // your module Name...
html(ng-app="phoneCatApp") // your declaration of module. mismatched.
If you still find trouble, you may referrer to this link,
http://jsfiddle.net/micronyks/8RG7y/
Note: This is just a basic demo (without Jade, Node.js, Express)
I have this about.js route and it works fine but I don't understand how / in router.get() would work while /about wouldn't?
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('about', { title: 'About' });
});
module.exports = router;
----------------- UPDATE ----------------------
It's basically what I got out of the box after installing express.js
except the about lines.
I expected router.get('/about' ...) in about.js would work but it threw an error and it worked with / instead and that's what bugs me.
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 routes = require('./routes/index');
var users = require('./routes/users');
var about = require('./routes/about');
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: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/about', about);
// 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;
The problem
When you define a route on your app.js as you did with app.use('/about', about);. You are already telling express that you expect requests to hit http://yourserver/about route.
If you try to define /about again inside your about.js with:
router.get('/', function(req, res, next) {
res.render('about', { title: 'About' });
});
What you're doing is tellig the Express that you will hit a /about inside your firstly declared /about. So it will expect requests on this route: http://yourserver/about/about
The solution
It's actually what you're using. Define a root route inside your about.js as:
router.get('/', function(req, res, next) {
res.render('about', { title: 'About' });
});
This way your app will be:
Modular since you're using different files for different routes (about.js, users.js)
Easier to read
With simplier routes inside each file, since you don't need to type /about everytime you wish to create a new route.
If you wish a http://yourserver/about/help simply add a handler inside your route file about.js as here:
router.get('/help', function(req, res, next) {
res.render('help', { title: 'Help' });
});
If you want the route /about work then you have to create another route:
router.get('/about', function(req, res, next) {
res.render('about-page', { title: 'About' });
});
because / will only work for the home page.
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');
});