Refresh specific page with Angular, Express and Jade (using html5mode) - javascript

I'm trying to refresh a page and execute client route to open a template inside ng-view
Index.jade
extends layouts/default
block content
section(data-ng-view)
script(type="text/javascript").
window.user = !{user};
default.jade
doctype html
html(lang='en', xmlns='http://www.w3.org/1999/xhtml', xmlns:fb='https://www.facebook.com/2008/fbml', itemscope='itemscope', itemtype='http://schema.org/Product')
include ../includes/head
body
div(data-ng-include="'static/modules/core/views/core.header.view.html'", data-role="navigation")
div(data-ng-include="'static/modules/core/views/core.index.view.html'", data-role="navigation")
div(data-ng-include="'static/modules/core/views/core.menu.view.html'", data-role="navigation")
div(data-ng-include="'static/modules/core/views/core.footer.view.html'", data-role="navigation")
include ../includes/foot
Server route
// Camera Routes
app.get('/api/cameras', cameras.all);
app.post('/api/cameras', auth.requiresLogin, cameras.create);
app.get('/api/cameras/:cameraId', cameras.show);
app.put('/api/cameras/:cameraId', auth.requiresLogin, auth.article.hasAuthorization, cameras.update);
app.del('/api/cameras/:cameraId', auth.requiresLogin, auth.article.hasAuthorization, cameras.destroy);
app.param('cameraId', cameras.camera);
// Home route
app.get('/', index.render);
express.js
/**
* Module dependencies.
*/
var express = require('express');
var flash = require('connect-flash');
var helpers = require('view-helpers');
var config = require('./config');
module.exports = function(app, passport) {
console.log('Initializing Express');
app.set('showStackError', true);
//Prettify HTML
app.locals.pretty = true;
//Should be placed before express.static
app.use(express.compress({
filter: function(req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
level: 9
}));
//Setting the fav icon and static folder
app.use(express.favicon());
app.use('/static',express.static(config.root + '/public'));
//Don't use logger for test env
if (process.env.NODE_ENV !== 'test') {
app.use(express.logger('dev'));
}
//Set views path, template engine and default layout
app.set('views', config.root + '/app/views');
app.set('view engine', 'jade');
//Enable jsonp
app.enable("jsonp callback");
app.configure(function() {
//cookieParser should be above session
app.use(express.cookieParser());
// request body parsing middleware should be above methodOverride
app.use(express.urlencoded());
app.use(express.json());
app.use(express.methodOverride());
//express/mongo session storage
app.use(express.session({ secret: '$uper$ecret$e$$ionKey'}));
//connect flash for flash messages
app.use(flash());
//dynamic helpers
app.use(helpers(config.app.name));
//use passport session
app.use(passport.initialize());
app.use(passport.session());
//routes should be at the last
app.use(app.router);
//Assume "not found" in the error msgs is a 404. this is somewhat silly, but valid, you can do whatever you like, set properties, use instanceof etc.
app.all('/*', function(req, res, next) {
res.render('index.jade', {'root': 'app/views/'});
});
app.use(function(err, req, res, next) {
//Treat as 404
if (~err.message.indexOf('not found')) return next();
//Log it
console.error(err.stack);
//Error page
res.status(500).render('500', {
error: err.stack
});
});
//Assume 404 since no middleware responded
app.use(function(req, res, next) {
res.status(404).render('404', {
url: req.originalUrl,
error: 'Not found'
});
});
});
};
HTML5 ENABLE
//Setting HTML5 Location Mode
angular.module('mean').config(['$locationProvider',
function($locationProvider) {
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix("!");
}
]);
Client router here, I want to show this template inside ng-view
angular.module('mean').config(['$stateProvider',
function ($stateProvider) {
$stateProvider.
state('viewCamera', {
url: "/cameras/:cameraId",
templateUrl: 'static/modules/cameras/views/cameras.camera.view.html'
});
}
]);
Index view with ui-view tag
<section data-ng-controller="MapController" data-ng-init="find()">
<div ui-view>
</div>
<div class="map-content" ng-class="{'map-content-left': cameraOpen != undefined}">
<leaflet defaults="defaults" center="center" class="map"></leaflet>
</div>
</section>
My html head
head
base(href='/')
What I want? When insert this url manually: localhost:3000/cameras/12, call server and get index to call client route and open the template inside ng-view
What's the problem? When I insert this url in browser, I get the index.jade with download mode
What I already tried?
Change the server route to this (apparently this return rendered index)
// Home route
app.get('*', index.render);
But the client route is never called
What's wrong?
EDIT 1
My dependencies version
"angular": "latest",
"angular-resource": "latest",
"angular-cookies": "latest",
"angular-mocks": "latest",
"angular-ui-utils": "0.0.4",
"angular-translate": "~2.5.2",
"angular-translate-loader-static-files": "~2.5.2",
"ngDialog": "~0.3.7",
"angular-leaflet-directive": "~0.7.10",
"leaflet.markercluster": "~0.4.0",
"angular-loading-bar": "~0.6.0",
"angular-ui-router": "~0.2.13"
I'm using Mean-Stack-Relacional from here: https://github.com/jpotts18/mean-stack-relational
EDIT 2
I was using angular-route, so I changed to ui-router to see if the problem was solved.
EDIT 3
Client Route core
//Setting up route
angular.module('mean').config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider.
state('login', {
url: '/login',
template: '',
controller: 'SessionController',
data: {
method: "login"
}
})
.state('signin', {
url: '/signin',
template: '',
controller: 'SessionController',
data: {
method: "signin"
}
})
.state('home', {
url: '/',
resolve: {
resetMap: function ($q, $location, $rootScope) {
$rootScope.$emit('rootScope:emit', '');
}
}
});
}
]);

#Scymex help me to find this issue:
For anybody who might be using Jade, here's a quick gotcha: div(ui-view) compiles to <div ui-view="ui-view"></div>. What you need is div(ui-view="").
So, you can have ui-view inside ng-include, but need do this trick
Font: https://github.com/angular-ui/ui-router/issues/679

You're using HTML5 routes with a hashbang fallback. What that means is you want to set your server up so that requests to /cameras/12 redirect to /#!/cameras/12. The server will then render your Angular application, which will detect that it wants to go to your viewCamera state and will rewrite the url on the client.
You can accomplish this by simply adding the following middleware to your express app:
app.use(function (req, res, next) {
res.set('Location', '/#!' + req.path)
.status(301)
.send();
});

Related

ENOENT: no such file or directory

I made a small project with authentication based on this example https://github.com/lyndachiwetelu/using-passport-with-sequelize-and-mysql. I had a mistake "Error: ENOENT: no such file or directory, open 'C:\Users\user\Desktop\using-passport-with-sequelize-and-mysql-master\app\views\layouts\main.hbs'"
But I did not point this way anywhere, it's strange. I beg you to help me, guys <3
I've alrready tried to make such way, and create such file(main.hbs), but in this case i can't reach another pathes ( dashboard, signin ). In this case they all have the same html-code from main.hbs
server.js :
var express = require('express')
var app = express()
var passport = require('passport')
var session = require('express-session')
var bodyParser = require('body-parser')
var env = require('dotenv').config()
var exphbs = require('express-handlebars')
//For BodyParser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// For Passport
app.use(session({ secret: 'keyboard cat',resave: true,
saveUninitialized:true})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
//For Handlebars
app.set('views', './app/views')
app.engine('hbs', exphbs({extname: '.hbs'}));
app.set('view engine', '.hbs');
app.get('/', function(req, res){
res.send('Welcome to Passport with Sequelize');
});
//Models
var models = require("./app/models");
//Routes
var authRoute = require('./app/routes/auth.js')(app,passport);
//load passport strategies
require('./app/config/passport/passport.js')(passport,models.user);
//Sync Database
models.sequelize.sync().then(function(){
console.log('Nice! Database looks fine')
}).catch(function(err){
console.log(err,"Something went wrong with the Database Update!")
});
app.listen(5000, function(err){
if(!err)
console.log("Site is live"); else console.log(err)
});
app/routes/auth.js :
var authController = require('../controllers/authcontroller.js');
module.exports = function(app,passport){
app.get('/signup', authController.signup);
app.get('/signin', authController.signin);
app.post('/signup', passport.authenticate('local-signup', { successRedirect: '/dashboard',
failureRedirect: '/signup'}
));
app.get('/dashboard',isLoggedIn, authController.dashboard);
app.get('/logout',authController.logout);
app.post('/signin', passport.authenticate('local-signin', { successRedirect: '/dashboard',
failureRedirect: '/signin'}
));
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/signin');
}
}
app/contrroller/authcontroller.js :
var exports = module.exports = {}
exports.signup = function(req,res){
res.render('signup');
}
exports.signin = function(req,res){
res.render('signin');
}
exports.dashboard = function(req,res){
res.render('dashboard');
}
exports.logout = function(req,res){
req.session.destroy(function(err) {
res.redirect('/');
});
}
In folder "app\views" only files with html-code, so i don't show them.
I still can't understand where program take this path \app\views\layouts\main.hbs
PROBLEM: Error: ENOENT: no such file or directory, open 'C:\Users\user\Desktop\using-passport-with-sequelize-and-mysql-master\app\views\layouts\main.hbs'
error_screen
structure_screen
Express-Handlerbars (the view engine you're using) expects a main layout file which you can see on the docs (search for "main.handlebars") https://github.com/ericf/express-handlebars
You can also see the directory structure express handlebars expects under https://github.com/ericf/express-handlebars#basic-usage
This acts as a "main" layout that your other views extend. So you can put common code in main such as a navbar etc.
You can either follow the docs or when you render your views use {layout:false} as one of the props passed in e.g
res.render('home', {layout: false});
and see if that works. You can also read about the defaultLayout here https://github.com/ericf/express-handlebars#defaultlayout
You could potentially try setting the default layout to false by default, though I don't know what effect this will have or if there are other unintended consequences. It might not even work at all.
app.engine('hbs', exphbs({extname: '.hbs', defaultLayout:false}));
Your best bet is to use a main layout, so you can put the common code in there, so if you wanted to update your logo for example you would only have to do it in 1 place rather than every view.
To do this, in your "views" directory create another directory called "layouts" and add a file called "main.hbs" with the following code in it. The {{{body}}} area is where your code from other views will be rendered.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Example App</title>
</head>
<body>
{{{body}}}
</body>
</html>

reloading the deep route after removing the '#' from url in express angular app throwing error [duplicate]

I would like to rewrite my URLs on my ExpressJS website. I've used this plugin, https://github.com/joehewitt/express-rewrite, but it doesn't work...
However, I might have made a mistake...
My app.js file :
var express = require('express')
, index = require('./routes/index.js')
, admin = require('./routes/admin.js')
, contact = require('./routes/contact.js')
, posts = require('./routes/posts.js')
, http = require('http')
, path = require('path')
, hash = require('./auth').hash
, db = require('./models')
, favicons = require('connect-favicons')
, rewriter = require('express-rewrite');
var app = express();
app.configure(function () {
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon(__dirname + '/public/images/FAVICON.ico'));
app.use(favicons(__dirname + '/public/images/apple-touch-icon.png'));
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser());
app.use(express.cookieSession({
secret: 'SECRET',
cookie: { access: false }
})
);
app.use(rewriter);
app.use(app.router);
app.use(function(req, res, next){
res.render('404.jade', {
title: "404 - Page Not Found",
showFullNav: false,
status: 404,
url: req.url
});
});
});
app.configure('development', function () {
app.use(express.errorHandler());
});
app.get('/', index.index);
app.get('/toto', rewriter.rewrite('/heytoto'));
db.sequelize.sync().complete(function(err) {
if (err) {
throw err
} else {
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'))
})
}
});
My error message :
Express
500 TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'match'
at Object.rewriter [as handle] (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express-rewrite/rewrite.js:3:26)
at next (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at Object.cookieSession [as handle] (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/cookieSession.js:113:5)
at next (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at Object.cookieParser [as handle] (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js:60:5)
at next (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at resume (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/static.js:60:7)
at SendStream.error (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/static.js:73:37)
at SendStream.EventEmitter.emit (events.js:126:20)
at SendStream.error (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/send/lib/send.js:147:51)
You could rewrite the URL before you get to the handler you want to use.
app.use(function(req, res, next) {
if (req.url === '/toto') {
req.url = '/heytoto';
}
next();
});
app.get('/heytoto', ...);
I've used a similar method to do URL rewrites with regular expressions.
So I had sort of the same issue. I wrote an app that uses the history API on browsers and I wanted to rewrite all non-static URLs back to index.html. So for static files I did:
app.configure(function() {
app.use('/', express.static(__dirname + '/'));
});
But then for the history API generated paths I did:
app.get('*', function(request, response, next) {
response.sendfile(__dirname + '/index.html');
});
This meant that any request that wasn't a file or directory in / (such as a URL generated by the history API) wouldn't be rewritten or redirected but instead the index.html file will be served and that then does all the JS routing magic.
Hopefully that's close to what you're looking for?
A solution that works without response.sendfile(..) is to use a rewrite middleware that is inserted prior to app.use(express.static(..)) like this:
// forward all requests to /s/* to /index.html
app.use(function(req, res, next) {
if (/\/s\/[^\/]+/.test(req.url)) {
req.url = '/index.html';
}
next();
});
// insert express.static(...)
This way, expressjs properly recognizes the rewrite. The static middleware will then take care of serving the file.
1) Your rewrite middleware must appear before the middleware/function that will handle the request.
Won't work:
app.use('/hello', () => sayHello() );
app.use(() => rewriteURLToHello()); //it's too late to try to rewrite a URL to /hello
Will work:
app.use(() => rewriteURLToHello()); //we can rewrite a URL to /hello
app.use('/hello', () => sayHello() ); //rewritten URL will be handled here
2) Your middleware must not be bound to the path you're trying to rewrite
Won't work:
app.use('/hello', (req, res, next) => {
//'/hello' has been trimmed from req.url
//req.url is / if the request was for /hello
req.url = '/goodbye'; //technically setting full path to /hello/goodbye
next(); //will only call other middleware in the /hello chain
});
app.use('/goodbye', () => sayBye()); //won't work
Will work:
app.use((req, res, next) => { //runs for every path. Same as .use('/',
//'/hello' has NOT been trimmed from req.url
//req.url is /hello if the request was for /hello
if (req.url.startsWith('/hello')) {
req.url = '/goodbye'; //full path now /goodbye
}
next(); //will continue calling all middleware
});
app.use('/goodbye', () => sayBye()); //will work
you could check the url with an if condition and use app.redirect to redirect to a certain url.
Try this:
app.get('/toto', function(req, res) {
res.redirect('/heytoto');
});

Index page changed after clicking on the "Home" link

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

external css files break jade view

Am new to node.js and am sorry if the answer to this question is too obvious
i build my app logic with all the routes and views and it work all fine , till i wanted to extend more styles to my views which i used Jade to build them as am using Express, the only change i did is i included bootstrap to my layout.jade
link(rel="stylesheet", href="bootstrap.min.css")
and my app break with 500 error.
note the bootstrap.min.css located in the public folder, also i noticed that in the console i got the right response before the error.
here is the error i got :
Error: Failed to lookup view "error" in views directory
"C:\Users\myuser\Desktop\mySpace\myApp\views"at Function.app.render
(C:\Users\myuser\Desktop\mySpace\myApp\node_modules\express\lib\application.js:493:17)
app.js
/*
* # db the string to connect the database as its used in mongoose_connection to store sessions.
*
*/
module.exports = function(items, db){
var express = require('express');
// Include the module to enable session using connect-mongo
var mongoStore = require('connect-mongo')(express);
// Include the module auth that using passpord module to authnticate user.
var passport = require('./auth');
// Include stylus module.
var stylus = require('stylus');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes')(items);
var app = express();
// Compile function for stylus.
function compile(str, path) {
return stylus(str).set('filename', path);
}
// 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());
//Middleware to store sessions
app.use(express.session({
secret : 'keyboard cat',
store : new mongoStore({
mongoose_connection : db
})
}));
// Initialize Passport! Also use passport.session() middleware, to support
// persistent login sessions (recommended).
// using passport as application midleware.
app.use(passport.initialize());
// telling session to use session in express.
app.use(passport.session());
//stylus middleware
app.use(stylus.middleware(
{
src: __dirname + '/public',
compile: compile
}
));
app.use(express.static(path.join(__dirname, 'public')));
/*
*Middleware to modifiy the header.
*/
app.use(function(req,res,next){
res.set ('X-Powered-By' , 'Myapp');
next();
});
app.use(app.router);
app.put('/app/setItem/:id', routes.setItem);
app.get('/app/findAllItem', routes.findAllitem);
app.get('/app/findById/:id',routes.findById);
app.get('/app/getJitems',routes.getJitems);
/*
*The routes of the login process 3 routes
*# the login form
*# the login post information and checking
*# the success redirect route
*/
// login form route
app.get('/login', routes.login);
// check user route
app.post('/login', passport.authenticate('local', {
failureRedirect: '/login',
successRedirect: '/user'
}));
//success login route
app.get('/user', routes.user);
/// catch 404 and forwarding 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.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.render('error', {
message: err.message,
error: {}
});
});
return app;
}
That's because it can't find "bootstrap.min.css", your 404 handler throws an error rather than generating a response, and you have no template for rendering error responses.
There are three problems you need to fix here:
Assuming bootstrap.min.css is in the root "public" directory and is meant to be used site-wide, it should be linked with the absolute path "/bootstrap.min.css", like so:
link(rel="stylesheet", href="/bootstrap.min.css")
Note the leading slash. Without the slash, a path like "bootstrap.min.css" is interpreted as a sibling of the current location, meaning that its inclusion on a page like "/users/500/example" would lead the browser to look for it at "/users/500/bootstrap.min.css".
Your "404 handler" should actually send a response, rather than throwing an error.
You should either:
create an error template,
replace the res.render call in the error handler with res.send,
or delete the error handler altogether and fall back to Express's default error handler.

Angular - 404 when directly visiting localhost:8080/somePage, but OK on href link?

Only after adding CRUD to my angular controller and service do I get a 404 error when I visit localhost:8080/somePage directly..
Cannot GET /somePage
The href links in my navbar that point to the same URL are still working though!
<li>somePage</li>
Some admin pages won't have page links though, so I need to get to them directly. Any suggestions?
Going to look at the API directly via localhost:8080/api/stuff does display the json:
[ {
"text": "item 1",
"done": false,
"id": "53402c4390dfad962a000001",
"_v": 0 } ]
Here's my appRoutes.js
angular.module('appRoutes', []).config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
// home page
.when('/', {
templateUrl: 'views/home.html',
controller: 'mainController'
})
//
.when('/somePage', {
templateUrl: 'views/somePage.html',
controller: 'mainController'
});
$locationProvider.html5Mode(true);
}]);
Here's the node+express server.js:
// set up ======================================================================
var express = require('express');
var app = express(); // create our app w/ express
var mongoose = require('mongoose'); // mongoose for mongodb
var port = process.env.PORT || 8080; // set the port
var database = require('./config/database'); // load the database config
// configuration ===============================================================
mongoose.connect(database.url); // connect to mongoDB database on modulus.io
app.configure(function() {
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users
app.use(express.logger('dev')); // log every request to the console
app.use(express.bodyParser()); // pull information from html in POST
app.use(express.methodOverride()); // simulate DELETE and PUT
});
// routes ======================================================================
require('./app/routes.js')(app); // load the routes
// listen (start app with node server.js) ======================================
app.listen(port);
console.log("App listening on port " + port);
And here's the Node.js routes.js, per Iqbal Fauzi's comment..
// load the stuff model
var Stuff = require('./models/stuff');
// expose the routes to our app with module.exports
module.exports = function(app) {
// api ---------------------------------------------------------------------
// get all the stuff
app.get('/api/stuff', function(req, res) {
// use mongoose to get all the stuff in the database
Stuff.find(function(err, stuff) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err)
res.send(err)
res.json(stuff); // return all the stuff in JSON format
});
});
// create stuff and send back all the stuff after creation
app.post('/api/stuff', function(req, res) {
// create stuff, information comes from AJAX request from Angular
Stuff.create({
text : req.body.text,
done : false
}, function(err, stuff) {
if (err)
res.send(err);
// get and return all the stuff after you create another
Stuff.find(function(err, stuff) {
if (err)
res.send(err)
res.json(stuff);
});
});
});
// delete stuff
app.delete('/api/stuff/:stuff_id', function(req, res) {
Stuff.remove({
_id : req.params.stuff_id
}, function(err, stuff) {
if (err)
res.send(err);
// get and return all the stuff after you create another
Stuff.find(function(err, stuff) {
if (err)
res.send(err)
res.json(stuff);
});
});
});
// application -------------------------------------------------------------
app.get('/', function (req, res) {
res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});
// commented out for testing this problem.. because this otherwise redirects..
// app.get('*', function (req, res) {
// res.redirect('/'); // redirect to / and index.html will be served
// });
};
Uncomment your app.get('*', function (req, res) and instead of redirecting it to '/' you will better return the index.html file, let AngularJS handle the browser URL for you.
app.get('*', function (req, res) {
res.sendfile('./public/index.html');
});

Categories

Resources