Simple AngularJS routing not working properly - angularjs

For some reason, I can't seem to route to the add screen. What am I doing wrong? Here's my app.js
var moviesApp = angular.module('moviesApp', ['ngRoute']);
moviesApp.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'partials/home.html',
controller: 'MoviesController'
})
.when('/add', {
templateUrl: 'partials/add.html',
controller: 'MoviesController'
})
.when('/edit', {
templateUrl: 'partials/edit.html',
controller: 'MoviesController'
});
});
Here's the anchor tag:
Add Movie
Which is contained within my home.html template which is a part of index.html.
The app doesn't crash...it just doesn't do anything.
Any thoughts on what I'm doing wrong?

It may be because of the change in the default hash-prefix in angularjs version 1.6. What you have written works in the given context: Proof
You can confirm this is the case by changing:
Add Movie
to:
Add Movie
If it works look at for possible solutions at:
AngularJS: ngRoute Not Working
If you want to make i behave as you expect (version 1.5) you could choose soultion 3 from the link:
3. Go back to old behaviour from 1.5 - set hash prefix manually
app.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);

set up a route start event to help debug the problem
.run(function ($rootScope) {
$rootScope.$on('$routeChangeStart', function (event, next, current) {
console.log(event);
console.log(current);
console.log(next);
console.log('$routeChangeStart: ' + next.originalPath)
});
});
just add this to the end of your route config
Just as a side note I would use a state provider over a route provider. State providers let you define a hierarchy. It's a little harder to work with but much more flexible.

Related

Argument 'mainController' is not a function, got undefined 1.4

There are a ton of examples of using the newer angular directives like ng-blur, ng-focus, form validation, etc. They all work great in a single page, or in plinkr, jsfiddle, etc. with the exception of the people who try to define the function on the global namespace, that mistake is WELL documented.
However, I was having a different problem.
I was using an example from Scotch.io. This one works great...until you introduce it into an SPA that is using angular-route :(
After many hours of fighting with the error 'Argument 'mainController' is not a function, got undefined', I found the answer in a comment from Hajder Rabiee.Thanks Hadjer, Love you man!
Hajder left this comment and in it, he says:
If you're using routes (high probability) and your config has a reference to a controller in a module that's not declared as dependency then initialisation might fail too.
E.g assuming you've configured ngRoute for your app, like
angular.module('yourModule',['ngRoute'])
.config(function($routeProvider, $httpProvider) { ... });
Be careful in the block that declares the routes,
.when('/resourcePath', {
templateUrl: 'resource.html',
controller: 'secondModuleController' //lives in secondModule
});
Declare secondModule as a dependency after 'ngRoute' should resolve the issue. I know I had this problem.
Even with this help it took me a minute to get it working, so I thought I would share my sample code here to help the next poor bastard that gets stuck on this.
First, in the place where i declare my routes:
var app = angular.module('sporkApp', ['ngRoute','validationApp']);
app.config(function ($routeProvider) {
$routeProvider
.when('/home',
{
controller: 'HomeController',
templateUrl: 'home/home.template.html'
})
.when('/tags',
{
controller: 'TagsController',
templateUrl: 'tags/tags.template.html'
})
.when('/test',
{
controller: 'mainController',
templateUrl: 'test/test.template.html'
})
.otherwise({ redirectTo: '/home' });
});
Then, you need to add your controller code somewhere, where it will get loaded in your shell page:
// create angular app
var validationApp = angular.module('validationApp', []);
// create angular controller
validationApp.controller('mainController', function($scope) {
// function to submit the form after all validation has occurred
$scope.submitForm = function() {
// check to make sure the form is completely valid
if ($scope.userForm.$valid) {
alert('our form is amazing');
}
};
});
Finally, you need to add the corresponding ng-app and ng-controller to some page element that wraps the controls you want to validate. I put the following inside of a div tag:
<div ng-app="validationApp" ng-controller="mainController">

angularjs with fullpage.js anchor and routing(complex)

I try to combine angularjs with fullpage.js on the index.page. Also, there are still some pages just rendered normally by route.
Here is my route in app.js
app.config(['$routeProvider', '$httpProvider', '$locationProvider', function($routeProvider, $httpProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
// Below are all sections at index page
.when('/#index', {
controller: 'WelcomeCtrl',
templateUrl: 'views/welcome/index.html'
})
.when('/#products', {
})
.when('/#learn', {
})
.when('/#help', {
})
.when('/#contact', {
})
// Other pages not using fullpage.js
.when('/cases', {
controller: 'CasesCtrl',
templateUrl: 'views/welcome/cases/index.html'
})
.when('/users', {
controller: 'UsersCtrl',
templateUrl: 'views/users/login.html'
})
.otherwise({
redirectTo: '/'
});
});
However, when I scroll the sections at the index, each calls my first routes rule, then renders the index page though the section is been correctly scrolled to.
Besides, the route rules with hash tags seems not working when setting the html5Mode true, I got urls become http://xxx/%23products, how to resolve this problem?
Thanks.
OK, I solved it by some hack.
First, I set the flag 'lockAnchors' to be 'true' in fullpage.js.
Second, I set a controller to the navbar directive, which provides a $scope.scrollTo(anchor), then after click and call scrollTo(anchor), I use ngSilent to silently change the url.
Finally, I check which page where I click the navbar.
If not the index page with fullpage.js, I use $location.path("/") to back to the index, then silently add the anchor to the url, with using fullpage.js method to scroll to the anchor(after a timeout about 1200~1500).

Unable to refresh page when using Angular, jQM, and Adapter

I'm working on a web page that is using Angular, jQuery Mobile, and the jQuery Mobile Angular adapter by tigbro. I have everything up an running and it works great except for one issue and that is if at any point if you refresh the page using the browser's refresh button it will give a 404 error as if it doesn't understand the route anymore. I'm not sure where the issue might be since it gets a little confusing with the two frameworks and the adapter working together and I'm new to all of these technologies.
IE happens to be the only browser this doesn't happen in and the difference seems to be in the url. Here is what it looks like when you browse to a page in IE:
http://site.com/SalesManagement/SalesManagementIndex.aspx#!/ViewNotes/4
Here is what it looks like when you browse to the same page in another browser like Chrome:
http://site.com/SalesManagement/ViewNotes/4
If you go to the first url in Chrome it will load the page and then rewrite the url to the 2nd one.
Below is my routing configuration:
var SalesManagementApp = angular.module('SalesManagementApp', [])
SalesManagementApp.config(['$routeProvider', '$compileProvider', function ($routeProvider, $compileProvider) {
$routeProvider
.when('/Search', { templateUrl: 'Views/GrowerSearchView.aspx' })
.when('/SearchResults', { templateUrl: 'Views/GrowerResultsView.aspx' })
.when('/ViewNotes/:growerIndexKey', { templateUrl: 'Views/NotesHistoryView.aspx' })
.when('/EditNote/:growerIndexKey/:noteIndexKey', { templateUrl: 'Views/UpsertNoteView.aspx' })
.when('/AddNote/:growerIndexKey', { templateUrl: 'Views/UpsertNoteView.aspx' })
.when('/', { templateUrl: 'Views/GrowerSearchView.aspx' })
.otherwise({ templateUrl: 'Views/GrowerSearchView.aspx' });
} ]);
I've read some about html5 mode verse hashbang mode but setting html5 mode to off or on in the configuration just made my routing not work at all. Any help would be much appreciated.
I figured this out thanks to a similar question on the github site for the adapter: https://github.com/opitzconsulting/jquery-mobile-angular-adapter/issues/163
The fix for this is to disable html5Mode in angular and prefix your links with the # character. This makes your urls a little uglier as you are no longer using the html5 history API but in my case that doesn't matter. Optionally you can specify a hash prefix (by default it seems to be !) but I set mine to empty string. I couldn't find any documentation telling me why this is useful but its important to know what the prefix is so you can properly set your links.
Below is my updated routing configuration. Notice I now inject the $locationProvider.
var SalesManagementApp = angular.module('SalesManagementApp', [])
SalesManagementApp.config(['$routeProvider', '$compileProvider', '$locationProvider', function ($routeProvider, $compileProvider, $locationProvider) {
$locationProvider.html5Mode(false).hashPrefix("");
$routeProvider
.when('/Search', { templateUrl: 'Views/GrowerSearchView.aspx' })
.when('/SearchResults', { templateUrl: 'Views/GrowerResultsView.aspx' })
.when('/ViewNotes/:growerIndexKey', { templateUrl: 'Views/NotesHistoryView.aspx' })
.when('/EditNote/:growerIndexKey/:noteIndexKey', { templateUrl: 'Views/UpsertNoteView.aspx' })
.when('/AddNote/:growerIndexKey', { templateUrl: 'Views/UpsertNoteView.aspx' })
.when('/', { templateUrl: 'Views/GrowerSearchView.aspx' })
.otherwise({ templateUrl: 'Views/GrowerSearchView.aspx' }); // jQuery Mobile seems to ignore the / and just use .otherwise.
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
if (!localStorage.SessionInfo)
window.location = '/Login.aspx';
} ]);
My links now look like: #/ViewNotes/{{growerIndexKey}}

$location hash prefix

I'm just starting out with Angular, so this might be a common newbie mistake but I am trying to achieve the following url format:
http://myapp.localhost/index.html#!/about
Which I believe should be the default for Angular?
This is my configuration:
angular.module('App', []).config(function($routeProvider, $locationProvider, VIEWS_ROOT) {
$locationProvider.html5Mode(false);
$locationProvider.hashPrefix = '!';
// Routing
$routeProvider.when('/', {templateUrl: './welcome.html', controller: 'WelcomeController'});
$routeProvider.when('/about', {templateUrl: './about.html', controller: 'AboutController'});
})
.run(function($rootScope) {
//...
});
In my html I have a simple anchor like so:
About
However when I click that anchor, the resulting URL constructed is:
http://myapp.localhost/index.html#/!/about
Which obviously fails to match any of my routes... a bit stumped on what's actually happening here, or what I'm doing wrong. I'm running off my local Apache instance under a vhost. There's nothing going on with mod_rewrite - so it looks like Angular is doing this.
It's a method to set the hashPrefix, not a property. $locationProvider.hashPrefix('!');

Infinite redirection when using $routeProvider

I have faced some problem trying to setup angular routing.
I have an application that is bootstrapped by hand (I need this feature, because I already have html5 navigation throughout whole site, and want angular to work only on certain page - it works fine).
But when I run my code I got some issues:
if .otherwise provided, I got infinite loop calling my controller and dying with Range error in Chrome
and I always got url redirection from hash version to non hash, even if I call $locationProvider.html5Mode(false);
Guess issues may be caused by fact that I am already using history.js and event handlers for statechange events, but for now I'm stuck with no clues.
Need your help to got some answer.
Thanks for your time.
And code.
HTML
<script>
if (typeof angular === 'undefined')
{
Modernizr.load({
load: [
'/static/css/angular.css',
'/static/js/libs/angular/angular.min.js',
'/static/js/files/angular/app.js',
'/static/js/files/angular/controllers.js',
'/static/js/files/angular/filters.js',
'/static/js/files/angular/services.js',
'/static/js/libs/angular/angular-resource.min.js',
],
complete: function () {
angular.bootstrap(document.getElementById('manager'), ['manager']);
}
});
} else {
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('manager'), ['manager']);
});
}
</script>
app.js
/* App Module */
var FM = angular.module('manager', ['managerFilters'])
.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('/home', { controller: FilesListCtrl, templateUrl: '/static/partials/1.html' })
.otherwise({ redirectTo: '/home' });
}]);
controllers.js
function FilesListCtrl($scope, $filter, $routeParams) {
app.log('FilesListCtrl')
}
#blesh #Flek thank you.
It was history.js to blame. When you try to use angular routing with it you'll have no option to set
$locationProvider.html5Mode to false. And other bugs occur like infinite redirection with default route provided.

Resources