I am trying to make a basic application using the MEAN Stack.
I have been struggling for the past hour or so to make a basic route work, but I fail miserably.
Whenever I access my application on / the template provided to the Angular route will not render the template, even if I can manually access it at templateUrl in the browser.
This is my code:
express.js
var express = require('express'),
bodyParser = require('body-parser'),
session = require('express-session'),
logger = require('morgan'),
cookieParser = require('cookie-parser');
module.exports = function(app, config){
app.set('views', config.rootPath + '/server/views');
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(session({secret: 'contact demo'}));
app.use(express.static(config.rootPath + '/public'));
};
routes.js
var mongoose = require('mongoose'),
Contact = mongoose.model('Contact');
module.exports = function(app, router) {
router.get('/partials/*', function(req, res) {
res.render('../../public/app/' + req.params[0]);
});
router.get('*', function(req, res) {
res.render('index');
});
app.use('/', router);
};
server.js
// Module Dependencies
var express = require('express'),
mongoose = require('mongoose');
// Initialize Express Application
var app = express(),
env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
// Config Parameters
var config = require('./server/config/config')[env];
// Invoke Express Config File
require('./server/config/express')(app, config);
// Invoke Mongoose Config File
require('./server/config/mongoose')(config);
// Invoke Routes File
require('./server/config/routes')(app, express.Router());
app.listen(config.port);
console.log('Listening on port ' + config.port + '...');
app.js
angular.module('demo', ['ngResource', 'ngRoute'])
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {templateUrl: '/partials/main/main'});
$locationProvider.html5Mode(true);
});
layout.jade
doctype
html
head
title Contact Management Application
link(rel="stylesheet" href="/vendor/bootstrap/dist/css/bootstrap.min.css")
link(rel="stylesheet" href="/css/style.css")
body(ng-app="demo")
block main-content
include scripts
index.jade
extends ../includes/layout
block main-content
h1 Hello World
section.content
div(ng-view)
main.jade
section.content
h1 I should be rendered!
EDIT
This is my folder structure:
--public/
--app/
--main/
--main.jade
--app.js
--css/
--vendor/
--server/
--config/
--express.js
--routes.js
--includes/
--layout.jade
--scripts.jade
--views/
--index.jade
--server.js
Where are you calling the REST commands in your angular code? It seems like you're just navigating to a different page within the app but you aren't telling it to pull from the server.
Related
The common middle for expressjs is the Route() middleware, but now I'm dropping jade and using handlebars. Handlebars itself have it ways to define the route. Because of that I may mess up my controllers inside my app.js.
Below is my app.js, any idea how can I split the route to a new file?
var express = require('express');
var app = express();
var exphbs = require('express-handlebars');
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
app.get('/',function(req,res){
res.render('index');
});
var port = Number(process.env.PORT || 3000);
app.listen(port);
Something like this?
//exported routes in ./routes/index.js
var routes = require('./routes');
//invoke routes
routes(app);
and routes file
module.exports = function(app) {
app.post('/etc', function(req,res) {
/* do route stuff */
});
/* other stuff goes here */
}
I'm trying work open page home of directory partials/home using ng-view and ng-view not working with express. A new page opens with render when acess http://localhost:3000/home. All routes defined for angular has no effect. I would like to know how to render my page partials/home.html in index.html using ng-view with express.
app.js
//módulos
var express = require('express');
var load = require('express-load');
var bodyParser = require('body-parser');
var app = express();
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var server = require('http').Server(app);
var io = require('socket.io')(server);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
//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(express.static(path.join(__dirname, 'public')));
load('routes').then('controllers').into(app);
server.listen(3000);
console.log('Site no ar ...');
module.exports = app;
Routes Express - index.js
module.exports = function (app) {
app.get('/', function(req, res){
res.render('index');
});
app.get('/:name', function(req, res){
var name = req.params.name;
res.render('partials/' + name);
});
app.get('*', function(req, res){
res.render('index');
});
};
Routes Angular - Location: public/app/app.js
var app = angular.module('appSiteFio',['ngRoute']);
app.config(function($routeProvider, $locationProvider){
// remove o # da url
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
templateUrl : 'index.html',
controller : 'mainController',
})
.when('/home', {
templateUrl : 'partials/home.html',
controller : 'homeController',
})
.otherwise ({ redirectTo: '/' });
});
I would suggest changing the index.js file to something like:
module.exports = function (app) {
app.use(express.static('/partials')); //here you can write your partials directory.
app.get('*', function(req, res){
res.render('index');
});
};
(Also change your templateUrl inside angular file with the partials prefix.);
that way angular will allways will be loaded and angular router will deal with all the views fetching from the static partials folder
I've created a node application with express. I try to separate the following layers which will give me the ability to test the application with unit testing...
The problem is that I don't know how to call to the router.js file which will stops in the post/get/delete application.
The server.js file looks as follows
http = require('http'),
app = require('./app')(),
http.createServer(app).listen(app.get('port'), function (err) {
console.log('Express server listening on port ' + app.get('port'));
});
This is the app.js file
var express = require('express'),
logger = require('morgan'),
bodyParser = require('body-parser'),
routesApp = require('./ro/route');
module.exports = function () {
var app = express();
app.set('port', process.env.PORT || 3005);
app.use(logger('dev'));
app.use(function (req, res, next) {
res.set('APP', 'User app');
next();
});
app.use(bodyParser.json());
app.use(routesApp);
return app;
};
This is the router.js, which will route the call to other module according to the http type like post/delete/get etc...
var handleGet = require('../controller/handleGet');
var handlePost = require('../controller/handlePost');
var express = require('express');
module.exports = function (app) {
var appRoute = express.Router();
app.use(appRoute);
appRoute.route('*')
.post(function (req, res) {
handlePost(req, res);
})
.get(function (req, res) {
handleGet(req, res)
})
Currently I've two questions:
How to make it work since when in debug It dump in
app.use(appRoute); on the router.js file?
The error is TypeError: undefined is not a function
Is it good way to structure the node app like in my post? I want to seperate all this layers like SOC, I'm fairly new to node and express and I try to build it to be modular and testable...
How to make it work since when in debug It dump in app.use(appRoute); on the router.js file? The error is TypeError: undefined is not a function
This fails because you don't pass app into the module when you require it in app.js, you would need to do something like
app.use(routesApp(app)); // <- this hurts my eyes :(
Is it good way to structure the node app like in my post?I want to sperate all this leyrs like SOC,I fairly new to node and express and I try to build it to be modular and testable...
Your definitely on the right track, keeping things separated is generally always a good idea. Testing is definitely one of the big pluses but it also helps with other things like maintainability & debugging.
Personally, I would make use of the bin directory for any start up script configuration
bin/www
var app = require('./app');
app.set('port', process.env.PORT || 3005);
var server = app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
This will help decouple your express app from all the environment setup. This should keep your app.js clean and only contain app-related config
app.js
var express = require('express')
, app = express()
, logger = require('morgan')
, bodyParser = require('body-parser')
, routes = require('./routes.js');
app.use(logger('dev'));
app.use(function (req, res, next) {
res.set('APP', 'User app');
next();
});
app.use(bodyParser.json());
app.use('/', routes);
...
module.exports = app;
Then finally, your routes.js should do nothing but handle your URLs
routes.js
var express = require('express')
, router = express.Router()
, handleGet = require('../controller/handleGet')
, handlePost = require('../controller/handlePost');
router.get('/', handleGet);
router.post('/', handlePost);
...
module.exports = router;
So Im trying to work AngularJS and Node. I am trying to set up client side routing but Im having some problems.
EDIT
So I changed up some code following https://github.com/scotch-io/starter-node-angular that #PareshGami suggested. I get the URLS to be hit but now the actual content doesnt load.
Here is my updated Code:
server.js:
var express = require('express'),
app = express(),
bodyParser = require('body-parser'),
mongoose = require('mongoose');
app.use(bodyParser.json());
require('./server/routes')(app);
app.use('/js', express.static(__dirname + '/client/js'));
app.use('/views', express.static(__dirname + '/client/views'));
app.use('/bower_components', express.static(__dirname + '/bower_components'));
app.use('/node_modules', express.static(__dirname +'/node_modules'));
app.listen(3000);
console.log('Im Listening...');
exports = module.exports = app;
my angular app.js:
(function (angular) {
'use strict';
var app = angular.module('eos', [
'ngRoute',
'ngResource',
'eos.opsCtrl',
'eos.dashboardCtrl'
]);
app.config(function ($routeProvider, $locationProvider){
$routeProvider.when(
'/',
{
templateUrl: 'views/dashboard.html',
pageName: 'Dashboard',
controller: 'dashboardCtrl'
}
);
$routeProvider.when(
'/ops',
{
templateUrl: 'views/ops.html',
pageName: 'Operations',
controller: 'opsCtrl'
}
);
$routeProvider.otherwise({redirectTo: '/'});
$locationProvider.html5Mode(true);
});
}(window.angular));
My routes.js (new):
var opsController = require('./controllers/opsController');
module.exports = function(app) {
//path.join(__dirname, 'client');
// server routes ===========================================================
// handle things like api calls
// authentication routes
app.get('/api/ops', opsController.list);
app.post('/api/ops', opsController.create);
// frontend routes =========================================================
// route to handle all angular requests
app.get('*', function(req, res) {
res.sendFile('index.html', { root: './client' });
});
};
Then rest is identical. And suggestions on why it is not loading the content in the ng-view?
FINALLY GOT IT TO WORK! My server.js was set up wrong.
Here is the correct server.js. Notice position of:
require('./server/routes')(app);
it needed to be father down for what I assume is the compile sequence
var express = require('express'),
app = express(),
bodyParser = require('body-parser'),
mongoose = require('mongoose'),
methodOverride = require('method-override');
// get all data/stuff of the body (POST) parameters
app.use(bodyParser.json());
// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
app.use(methodOverride('X-HTTP-Method-Override'));
app.use('/js', express.static(__dirname + '/client/js'));
app.use('/views', express.static(__dirname + '/client/views'));
app.use('/bower_components', express.static(__dirname + '/bower_components'));
app.use('/node_modules', express.static(__dirname +'/node_modules'));
require('./server/routes')(app);
app.listen(3000);
console.log('Im Listening...');
exports = module.exports = app;
I was directed by PareshGami to look over this site 'setting-up-a-mean-stack-single-page-application'. After following that I was able to get the routing to work. The key to my problem was the ordering of my server.js file and the require('./server/routes')(app); part.
I get an error Cannot Get /. this is my folder structure
This is the route.js file:
//route.js
'use strict';
var app = require('../../config/express');
var router = app.Router();
/* Get Home Controller */
var homeController = require('../controllers/index');
router.get('/index', homeController.index); //it isn't recognized
app.use('/', router);
'use strict';
/*
* GET /
* Home Page
*/
exports.index = function(req, res){
res.render('index', {
'pageTitle': 'Express page'
});
};
'use strict';
/* Import Express module */
var express = require('express');
var path = require('path');
//var bodyParser = require('body-parser');
/* Import env config parameters */
var settings = require('./env/settings');
/* Create express server */
var app = express();
/* Settings Application */
app.set('port', settings.port);
app.set('views', path.join(__dirname, '/frontend/views'));
app.set('view engine', 'jade');
//app.use(bodyParser.json());
//app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(__dirname + '/assets'));
module.exports = app;
I know that it is a problem on routing but I have tried to fix it
Cannot Get / is exactly what is says. You have not defined any routes that match that path. You have defined /index, but not /, and they are two different URLs. index.html-style behavior is not provided by Express in routes. It is available with the static-file middleware if you want it though.
So change it to:
router.get('/', homeController.index);
or if you also want /index to work, just do both:
router.get('/', homeController.index);
router.get('/index', homeController.index);