ngRoute doesn't seem to work - angularjs

I have a web app that doesn't seem to work at all if I try to use ngRoute approach to changing primary page view. The routing config looks like:
var app;
app = angular.module('genehaxx', ['ngGrid','ngRoute', 'ngSanitize', 'ui.bootstrap','genehaxx.filters', 'genehaxx.services'])
.config(function($routeProvider){
//route setup
$routeProvider
.when('/workflows', {
templateURL: '/partials/workspace_view.html',
controller: 'MainController'
})
.when('/jobs', {
templateURL: '/partials/submissions_view.html' ,
controller: 'MainController'
})
.when('/', {
templateURL: '/partials/analyses_view.html',
controller: 'MainController'
})
.when('/analyses', {
redirectTo: '/'
})
.otherwise({
redirectTo: '/'
});
});
function MainController($scope, $modal, $rootScope, User, Data, Workflow, Step){
//lots of proprietary code here..
}
I have tried it with and without the '/' in front of partials. I have tried it both with its normal web-server reverse proxied under nginx and directly under http-server from its directory. In both cases there is no evidence whatsoever that the partials pages are ever requested from the server. The main view is a bit hairy to post in entirety but the relevant bits look like:
<!doctype html>
<html lang="en" ng-app="genehaxx" >
<head>
<meta charset="utf-8">
<title>Welcome to Genengine!</title>
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="css/app.css"/>
<link rel="stylesheet" href="css/ng-grid.css">
<script src="lib/jquery-2.0.2.js"></script>
<script src="libs/angular/angular.js"></script>
<script src="libs/angular-route/angular-route.min.js"></script>
<script src="libs/angular-sanitize/angular-sanitize.js"></script>
<script src="lib/transition.js"></script>
<script src="lib/bootstrap-custom/ui-bootstrap-custom-tpls-0.10.0.js"></script>
<script src="lib/ng-grid-2.0.7.debug.js"></script>
<script src="js/app.js"></script>
<script src="js/filters.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore.js"></script>
<script src="js/objects.js"></script>
<script src="js/services2.js"></script>
<script src="js/dropdownToggle.js"></script>
</head>
<body>
<div id="main">
<div ng-view></div>
</div>
</body>
</html>
I have left off the navbar stuff as it seems irrelevant and I get the same results clicking it or directly entering the url with #whatever. The /libs directories have the latest angular, angular-route, angulare-sanitize from bower.
Small samples I tried plugging in my libraries and partials seem to work which is even more frustrating. I have been stumped on this for days. I hacked around it in production with mess of ng-includes and some "clever" code but I would rather get this working. Anything pop out? When I say it doesn't work, again I mean that I see no evidence that any routing occurred in that these partials are never requested from the server.

You have typos inside of your when calls:
Example:
templateURL: '/partials/workspace_view.html',
should be
templateUrl: '/partials/workspace_view.html',
(notice the difference in caps, templateURL changes to templateUrl)

Couple things
1 - Stringify MainController
.
$routeProvider
.when('/workflows', {
templateURL: '/partials/workspace_view.html',
controller: 'MainController'
})
.when('/jobs', {
templateURL: '/partials/submissions_view.html' ,
controller: 'MainController'
})
.when('/', {
templateURL: '/partials/analyses_view.html',
controller: 'MainController'
})
.when('/analyses', {
redirectTo: '/'
})
.otherwise({
redirectTo: '/'
});
2 - You don't need ng-controller on body. ngRoute will bind the controller to the view for you. However, make sure you have MainController defined in your app, otherwise angular will throw an error at you

I see that #Mark Kline's solution solved your issue, but I would like to make suggestion that might help you in the long run.
You mention in a comment that your controller is complicated, as such I would highly recommend that you break it up into smaller controllers where each is used only to control one of the routes. From experience if you are using routing to develop an application then using one controller is going to get very large quickly, and in the long run be very hard to maintain. I have tried, in previous apps to use a single controller for several different views and it tends to get out of hand rather quickly.
If you are able, I highly suggest that you separate as much functionality as possible to save yourself a lot of future headaches, it is going to make your code easier to read, maintain, and debug.

Related

Angular SPA can't change nested views [duplicate]

I was expecting to see this question on Stackoverflow but didn't. Apparently I'm the only one having this problem that seems to me to be very common.
I have a basic project I am working on but the routes don't seem to work even though everything I've done so far seems to be right.
I have this piece of html in my index.html file:
<html>
<head ng-app="myApp">
<title>New project</title>
<script src="https://code.angularjs.org/1.6.0/angular.min.js"></script>
<script src="https://code.angularjs.org/1.6.0/angular-route.min.js"></script>
<script src="app.js"></script>
</head>
<body>
Add Quote
<div ng-view ></div>
</body>
</html>
and here is my app.js:
var app = angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/add-quote', {
templateUrl: 'views/add_quote.html',
controller: 'QuoteCtrl'
})
.otherwise({ redirectTo: '/' });
}]);
Now when I just visit the page, here is what I get in the url:
http://localhost:8000/admin#!/
and when I click on the Add quote button, I get this:
http://localhost:8000/admin#!/#%2Fadd-quote
What can be the problem here?
Thanks for help
Simply use hashbang #! in the href:
Add Quote
Due to aa077e8, the default hash-prefix used for $location hash-bang URLs has changed from the empty string ('') to the bang ('!').
If you actually want to have no hash-prefix, then you can restore the previous behavior by adding a configuration block to your application:
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
For more information, see
AngularJS GitHub Pull #14202 Changed default hashPrefix to '!'
AngularJS Guide - Migration - aa0077e8
Sorry to get on my high horse but... How did this get released? This is massive, breaking bug. — #MiloTheGreat
The breaking change as by #14202 should be reverted as the reference specification was already officially deprecated #15715
I'm going to close this issue because we haven't got any feedback. Feel free to reopen this issue if you can provide new feedback.
— https://github.com/angular/angular.js/issues/15715#issuecomment-281785369
Simply include the ! into the href:
<body>
Add Quote
<div ng-view ></div>
</body>
I couldn't get routing to work in 1.6.4 so I decided to use angular 1.5.11 and routing works fine although I needed to define all my routings in when(..) functions with trailing "/"
If sticking to an older version of angular is an option for you then consider it since it may save your nerves...
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/layoutandviewbox", {
templateUrl : "views/layout-and-viewbox.html"
})
.when("/basicshapes", {
templateUrl : "views/basic-shapes.html"
})
.when("/advancedshapes", {
templateUrl : "views/advanced-shapes.html"
})
.when("/groups", {
templateUrl : "views/groups.html"
})
.when("/transformations", {
templateUrl : "views/transformations.html"
})
.when("/effects", {
templateUrl : "views/effects.html"
})
.when("/", {
templateUrl : "views/basic-shapes.html"
});
});
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$locationProvider.hashPrefix('');
$routeProvider
.when('/add-quote', {
templateUrl: 'views/add_quote.html',
controller: 'QuoteCtrl'
})
.otherwise({ redirectTo: '/' });
}]);
Try this one might Help...
In html or view Page
<body>
Home
<div ng-view></div>
</body>
In Script Page
var app=angular
.module('myModule',['ngRoute'])
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/Home', {
templateUrl: 'FolderName/Home.html',
controller: 'homeCtr'
})
$locationProvider.hashPrefix('');
});

angularjs 1.6.0 (latest now) routes not working

I was expecting to see this question on Stackoverflow but didn't. Apparently I'm the only one having this problem that seems to me to be very common.
I have a basic project I am working on but the routes don't seem to work even though everything I've done so far seems to be right.
I have this piece of html in my index.html file:
<html>
<head ng-app="myApp">
<title>New project</title>
<script src="https://code.angularjs.org/1.6.0/angular.min.js"></script>
<script src="https://code.angularjs.org/1.6.0/angular-route.min.js"></script>
<script src="app.js"></script>
</head>
<body>
Add Quote
<div ng-view ></div>
</body>
</html>
and here is my app.js:
var app = angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/add-quote', {
templateUrl: 'views/add_quote.html',
controller: 'QuoteCtrl'
})
.otherwise({ redirectTo: '/' });
}]);
Now when I just visit the page, here is what I get in the url:
http://localhost:8000/admin#!/
and when I click on the Add quote button, I get this:
http://localhost:8000/admin#!/#%2Fadd-quote
What can be the problem here?
Thanks for help
Simply use hashbang #! in the href:
Add Quote
Due to aa077e8, the default hash-prefix used for $location hash-bang URLs has changed from the empty string ('') to the bang ('!').
If you actually want to have no hash-prefix, then you can restore the previous behavior by adding a configuration block to your application:
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
For more information, see
AngularJS GitHub Pull #14202 Changed default hashPrefix to '!'
AngularJS Guide - Migration - aa0077e8
Sorry to get on my high horse but... How did this get released? This is massive, breaking bug. — #MiloTheGreat
The breaking change as by #14202 should be reverted as the reference specification was already officially deprecated #15715
I'm going to close this issue because we haven't got any feedback. Feel free to reopen this issue if you can provide new feedback.
— https://github.com/angular/angular.js/issues/15715#issuecomment-281785369
Simply include the ! into the href:
<body>
Add Quote
<div ng-view ></div>
</body>
I couldn't get routing to work in 1.6.4 so I decided to use angular 1.5.11 and routing works fine although I needed to define all my routings in when(..) functions with trailing "/"
If sticking to an older version of angular is an option for you then consider it since it may save your nerves...
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/layoutandviewbox", {
templateUrl : "views/layout-and-viewbox.html"
})
.when("/basicshapes", {
templateUrl : "views/basic-shapes.html"
})
.when("/advancedshapes", {
templateUrl : "views/advanced-shapes.html"
})
.when("/groups", {
templateUrl : "views/groups.html"
})
.when("/transformations", {
templateUrl : "views/transformations.html"
})
.when("/effects", {
templateUrl : "views/effects.html"
})
.when("/", {
templateUrl : "views/basic-shapes.html"
});
});
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$locationProvider.hashPrefix('');
$routeProvider
.when('/add-quote', {
templateUrl: 'views/add_quote.html',
controller: 'QuoteCtrl'
})
.otherwise({ redirectTo: '/' });
}]);
Try this one might Help...
In html or view Page
<body>
Home
<div ng-view></div>
</body>
In Script Page
var app=angular
.module('myModule',['ngRoute'])
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/Home', {
templateUrl: 'FolderName/Home.html',
controller: 'homeCtr'
})
$locationProvider.hashPrefix('');
});

angular: updating a view without page reload

I have a rootScope json array that's viewed is several controllers, and gets updated in yet another controller. The json array contains urls that get updated. The view controllers show updated urls about half the time, but if I reload the page, I do get updated views 100% of the time.
I have tried using $scope.$apply() and $timeout, but they made no difference.
Could someone please tell me what angular tools are out there for this? I'm hoping there is a simple approach to it.
Going off of my earlier comment:
Index
<!doctype html>
<html ng-app="myapp">
<head>
<!--Head stuff-->
</head>
<body>
<div ng-view=""></div>
<!-- Scripts, other stuff -->
</body>
</html>
Main Script
'use strict';
angular
.module('myapp', [
//...
'ngRoute',
//...
])
.config(function (..., $routeProvider, ...) {
$routeProvider
.when('/404', {
templateurl: '404.html',
controller: 'ErrorCtrl',
controllerAs: 'errorCtrl',
title: 'You are lost'
})
.when('/', {
templateUrl: 'views/home.html',
controller: 'HomeCtrl',
controllerAs: 'homeCtrl',
title: 'Home'
})
.when('/contact', {
templateUrl: 'views/contact.html',
controller: 'ContactCtrl',
controllerAs: 'contactCtrl',
title: 'Contact Us'
})
.otherwise({
redirectTo: '/404'
});
//...
})
.run (function (...) {
//...
});
Usage
Contact Us
You'd be taking all of the base template code that's common to your pages and be including that on index. Basically, the stuff that doesn't change will always be there. Otherwise, take it off of the main page and put it into a template file with its own controller. Alternatively, have some shared controllers and just use the views as templates, then shovel all of the functionality into directives. I actually prefer the latter method, but the former is shown above.
What's noteworthy about this solution is that the page is only actually loaded once. Since you stay on the index whenever you navigate to a different view, you only need to grab the HTML for the new template from your server and inject it into the view (which ngRoute takes care of). I believe that by default you'll have a # in your URL, so you'll probably want to enable HTML5 mode.$locationProvider into your config function and then add this line:
$locationProvider.html5Mode ({ enabled: true });
You also need to add a base to the head element of your index file:
<base href="/" />
Homework: Routes tutorial, HTML5 mode
If you use Grunt, you might also want to look into ngTemplates. It can really boost performance.

ngRoute SyntaxError: Unexpected token < not solved by adding "/"

Good afternoon everyone,
I started AngularJS a few days ago and, if I usually find my all answers here, I have a mysterious error...
Here is the evil error:
Error in event for (unknown): SyntaxError: Unexpected <
extensions::uncaught_exception_handler
Here is for my code:
HTML (index.html)
<script src="/app/main.controller.js" type="text/javascript" charset="utf-8"></script>
<script src="/app/controllers/test.controller.js" type="text/javascript" charset="utf-8"></script>
Home
Design
ANGULAR (main.controller.js)
function RouteProvider ($routeProvider) {
$routeProvider
.when("/", {
templateUrl: "/app/views/home.html",
controller: "homeCtrl"
})
.when("/design", {
templateUrl: "/app/views/design.html",
controller: "testCtrl"
})
.otherwise({
redirectTo: "/"
});
}
STRUCTURE
index.html
/app
main.controller.js
/controllers
/views
This is the part of the code concerned by my route config.
The error happens whenever I activate the links above...
Thank you for your time!
(It's my first post, sorry if it's messy and if you need more code juste ask and I'll add it :])

Update ng-class on HTML tag when routing

I'm writing a Chrome extension using AngularJS. The UI is served via a browser action popup and as the content changes I sometimes need to change the size of the popup. The only way I've been able to do this is to change the CSS sizing attributes on the HTML and BODY tags via conditional updates of the class, i.e.
<!DOCTYPE html>
<html lang="en" ng-app="oApp" ng-controller="QuestionsCtrl" ng-class="{true:'expand'}[doExpand]">
<head>
...
</head>
<body ng-class="{true:'expand'}[doExpand]">
...
I have an ng-click on a control that sets 'doExpand' and this works nicely. However, I'm updating the app now to use routing to display multiple views. In doing that I'm removing the inline controller declaration...
<!DOCTYPE html>
<html lang="en" ng-app="oApp" ng-class="{true:'expand'}[doExpand]">
...
... and defining it in the routing config:
var oApp = angular.module('oApp', ['ngRoute', 'oControllers']);
oApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/login', {
templateUrl: '/partials/login.html',
controller: 'LoginCtrl'
}).
when('/board', {
templateUrl: 'partials/board.html',
controller: 'QuestionsCtrl'
}).
when('/board/:questionId', {
templateUrl: 'partials/question-detail.html',
controller: 'QuestionDetailCtrl'
}).
otherwise({
redirectTo: '/login'
});
}
]);
The routing is working but the problem is that the HTML tag is now outside the scope of the controller since that's now on the views themselves. I can stick the BODY tag in the views I suppose, but can't do the same for the HTML tag since the JS includes need to be in the head, etc. (and other reasons)
Can someone offer me advice on how to handle this scenario? Thank you!

Resources