Reputation: 668
I have angular working with expressjs and everything for the most part is working, however I am running into conflicts with routes in express and angular
app.js
app.get('/',routes.index);
app.get('/about/:name', aboutRoutes.partials);
app.get('/partials/:name', routes.partials);
//authentication
//app.get('/app', ensureAuthenticated ,appRoutes.app);
app.get('/app',appRoutes.app);
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/[a-z]{0,100}',routes.index)
Routes
var homeContent = require('../content-config/home.json');
exports.index = function(req, res) {
res.render('template', {
headerTitle: homeContent.headerTitle,
headerContent: homeContent.headerContent,
mainTitle: homeContent.mainTitle,
mainContent: homeContent.mainContent,
employersTagLine: homeContent.employersTagLine,
candidatesTagLine: homeContent.candidatesTagLine,
providersTagLine: homeContent.providersTagLine,
fundingTagLine: homeContent.fundingTagLine,
howItWorksTitle: homeContent.howItWorksTitle,
partials: {
head: 'partials/head',
header: 'partials/header',
footer: 'partials/footer',
maincontent: 'homepage',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
learnAboutUs: 'partials/learn-about-us',
industries: 'partials/industries-blue'
}
});
};
exports.partials = function (req, res) {
var name = req.params.name;
var content = "";
res.render('partials/'+name,content);
};
var employersContent = require('../content-config/employers.json'),
candidatesContent = require('../content-config/candidates.json'),
providersContent = require('../content-config/providers.json'),
fundingContent = require('../content-config/funding.json');
exports.us = function(req, res) {
res.render('about/us', {
partials: {
header: 'partials/header',
footer: 'partials/footer',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal'
}
});
};
exports.partials = function (req, res) {
var name = req.params.name;
var content = "";
switch(name)
{
case "funding":
content ={
headerTitle: fundingContent.headerTitle,
headerContent: fundingContent.headerContent,
explanation: fundingContent.explanation,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal'
}
};
break;
case "candidates":
content = {
headerTitle: candidatesContent.headerTitle,
headerContent: candidatesContent.headerContent,
explanationTitle: candidatesContent.explanationTitle,
explanationContent: candidatesContent.explanationContent,
explanationBullets: candidatesContent.explanationBullets,
resumeTitle: candidatesContent.resumeTitle,
resumeContent: candidatesContent.resumeContent,
funnelTitle: candidatesContent.funnelTitle,
funnelContent: candidatesContent.funnelContent,
partials: {
header: 'partials/header',
industries: 'partials/industries-blue',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel-candidate',
output: 'partials/candidate-grid'
}
}
break;
case "employers":
content = {
headerTitle: employersContent.headerTitle,
headerContent: employersContent.headerContent,
explanationTitle: employersContent.explanationTitle,
explanationContent: employersContent.explanationContent,
explanationBullets: employersContent.explanationBullets,
factsTitle: employersContent.factsTitle,
facts: employersContent.facts,
funnelTitle: employersContent.funnelTitle,
funnelContent: employersContent.funnelContent,
buildVsBuyTitle: employersContent.buildVsBuyTitle,
buildVsBuyContent: employersContent.buildVsBuyContent,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel',
output: 'partials/output'
}
};
break;
case "providers":
content = {
headerTitle: providersContent.headerTitle,
headerContent: providersContent.headerContent,
explanationTitle: providersContent.explanationTitle,
explanationContent: providersContent.explanationContent,
explanationBullets: providersContent.explanationBullets,
buildVsBuyTitle: providersContent.buildVsBuyTitle,
buildVsBuyContent: providersContent.buildVsBuyContent,
partials: {
header: 'partials/header',
footer: 'partials/footer',
learnAboutUs: 'partials/learn-about-us',
signupModal: 'partials/signup-modal',
verisignSeal: 'partials/verisign-seal',
funnel: 'partials/funnel',
output: 'partials/output'
}
};
break;
}
res.render('about/'+name,content);
};
Angular App.js
'use strict';
// Declare app level module which depends on filters, and services
angular.module('myApp', [
'ngRoute',
'myApp.controllers',
'myApp.filters',
'myApp.services',
'myApp.directives'
]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/homepage',
controller: 'MyCtrl1'
}).
when('/about/:name', {
templateUrl: name,
controller: 'MyCtrl1'
}).
when('/funnel', {
templateUrl: 'partials/funnel',
controller: 'MyCtrl2'
}).
otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
});
If I go to / then the full page renders and pulls the homepage partial in with no problem
If I go to /funnel it works the same way.
If I got to about/randompage it will render the partial on its own with none of the rest of the page but if I click to go to about/randompage from the homepage it will pull in the partial into the page like it is supposed to. What can I do to stop the route conflicts?
Upvotes: 1
Views: 1607
Reputation: 7196
You have two different things going on here. First, is the difference between the browser making a request to the server and angular making a request to the server.
When your browser requests '/funnel' it matches your catchall route and returns the index page as you expect. What happens then is that Angular (and all your other static assets load) and then Angular's client router matches '/funnel' to your Angular route. Since the route template is partials/funnel it then makes a request to the server for partials/funnel and loads the result.
When you directly request /about/randompage it matches one of your partial routes 'about/:name' which only returns the partial. Angular makes this same request '/partials/' because your mapping of templateUrl:name makes it relative to the route.
In this basic sense you could consider it a "conflict" because your server-side routes should NOT match your client-side routes since you need to respond with the initial load (index.html, all the angular js files, etc) every time the browser comes in fresh.
Typically what I do when supporting deep-linking is to keep the angular template files alongside of all the static resources of the module. The templateUrl paths should all reference them statically (like templateUrl: '/js/about/templates/person.html') Express can serve them as static files just fine (basic html). The only true "routes" on the server are API endpoints for ajax/service calls, etc.
If you want to wrap it in a module like you have with routes and aboutRoutes, then I'd suggest keeping everything inside of a '/templates' or '/partials' path parent. However, it's an unnecessary step unless you are actually rendering your templates via Jade or some other views engine. If they are simple html just serve them up using express.static as normal.
I use a catchall similar to your's except I don't use regex. Not sure if it's better or worse but it's a little clearer to read IMO. app.use('*', routes.index);
That way all client-side routes, when used for deep-linking, will fall through and always return the index page and allow Angular to manage the client routes. Hope that helps!
Upvotes: 3