Angular route with $routeProvider - javascript

I'm trying to understand the routing before I start building my app but it doesn't seem to work.
I have a basic app for tests in which I created 3 html files matching 3 different views and I wish to change the displayed view depending on the routes.
But I always see the index view.
Here are the files :
app.js :
'use strict';
angular.module('BalrogApp', ['ngRoute', 'ui.bootstrap', 'BalrogApp.controllers'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '../index.html'
})
.when('/requests', {
templateUrl: '../views/requestsList.html'
})
.when('/projects', {
templateUrl: '../views/projectsList.html'
})
.otherwise({
redirectTo: '/lol'
});
}]);
requestsController.js :
'use strict';
var requestsControllerModule = angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);
requestsControllerModule.controller('requestsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Request";
this.studentMark = 75;
});
projectsController.js :
'use strict';
var projectsControllerModule = angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);
projectsControllerModule.controller('projectsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Project";
this.studentMark = 75;
});
The html files are almost the same except for some words and for the controller associated to each of them.
Here are the few lines that change between html wiews :
index.html :
index view
<div class="row-fluid" ng-controller="requestsController as rc">
<div class="span2">{{rc.studentName}} </div>
</div>
requestsList.html :
Request view
<div class="row-fluid" ng-controller="requestsController as r">
<div class="span2">{{r.studentName}} </div>
</div>
projectsList.html
Project view
<div class="row-fluid" ng-controller="projectsController as p">
<div class="span2">{{p.studentName}} </div>
</div>
Byt no matter what the route is, if I added '/projects' or '/requests' to the url, I stay on the index view.
Any idea what I am doing wrong ?

Make sure you have ng-view attribute or element set in your index.html. If it is absent the router won't work.
Another good practice would be to set your view controller on the router, like so:
$routeProvider
.when('<route_name>', {
templateUrl: '../<tempate>.html',
controller: '<controller_name>',
controllerAs: 'myController'
})

1. On your base file (usually index.html), make sure you have an ng-view directive that will be used to load all the partial views
2. Are all your html templates in the same location as the base file? If yes, the instead of having the templateUrl as "../index.html" you could try setting it to "/index.html" instead. The first checks for the html file outside of the directory where the base file is located, while the second checks for it in the same directory

Related

Pulling list item data through to a new view created by the scope data

Although there are a few of these questions rocking about, none of them seem to have a good working example and i cant seem to figure out how to apply it to my project.
What i want to do is pull the data through from the list item into another view to use as a profile page.
JS
var app = angular.module('passDataDemo', ['ngRoute']);
// Configure our routes
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
// Route for the global controller
.when('/', {
templateUrl: 'list.html'
})
// Route for profile
.when('/:item.firstname', {
templateUrl: 'listItemProfile.html'
})
// Fallback
.otherwise({
redirectTo: '/'
});
}]);
// Main controller
app.controller('mainCtrl', ['$scope', '$http', function($scope, $http) {
$http.get('items.json').success(function(data) {
$scope.items = data;
});
}]);
View 1 html
<ul ng-repeat="item in items">
<li>
<p>{{item.firstname}}</p>
<p>{{item.surname}}</p>
<button ng-click="viewTheProfileView()">View Profile</button>
View 2 html
<h1>ITEM PROFILE</h1>
<p>{{item.firstname}}</p>
<p>{{item.surname}}</p>
Here is my Plunker - https://plnkr.co/edit/gZj5gOZEcCOLNbdxwduw?p=preview
After looking at your plunker, I see that you are only using one controller for all of your views. Because of this, you would only need to set the value of $scope.item and it will show up in your listItemProfile.html. Therefore, I would change your button to pass in the current item to the controller: <button ng-click="viewTheProfileView(item)">View Profile</button>.
Then in your controller:
$scope.viewTheProfileView = function(item) {
$scope.item = item;
};
This will allow clicking the ITEM PROFILE button in index.html to display the correct information.

Spring MVC + Angular routing gives 404

I have created a Spring MVC project along with a client side angular app.
For the angular app,
Here is the content of /webapp/resources/js/app.js file
'use strict';
// Declare app level module which depends on views, and components
var app = angular.module('myApp', [
'ngRoute',
'ngMaterial',
'rzModule'
]);
app.config(function ($routeProvider) {
$routeProvider
.when('/views/1', {
controller: 'MyController',
templateUrl: '/views/view1.html'
})
.when('/views/2', {
controller: 'MyController',
templateUrl: '/views/view2.html'
})
.when('/views/file-upload', {
controller: 'MyController',
templateUrl: '/views/file-upload.html'
})
.otherwise({
redirectTo: '/'
});
});
But the given templateUrls like "templateUrl: '/views/file-upload.html'" are seem to be not working.
The views are within /webapp/WEB-INF/views folder.
I want to know which addresses should I give inorder to route this views in app.js

How to work with index.html, ui.router, and redirect back to home

I use for testing python simpleserver to test my angular app. I new to ui.router and trying to get index.html work properly and when trying to go home using e.g.
<a class="navbar-brand" ui-sref="/">MyApp</a>
To navigate back to home or index.html
Code
"use strict";
var mainApp = angular.module('mainApp', ['ui.router']);
mainApp.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/#');
$stateProvider
.state('/', {
url: '/',
templateUrl: 'index.html',
controller: 'mainController'
});
});
mainApp.controller('mainController',
function($state, $log, $scope, $rootScope, $http) {
$scope.test = 'foobar';
}
);
Any help would be appreciated to fix it.
Problem Plunkr
You are rendering index.html again inside your ui-view div, so techically you should have html that would have your home page content
myHomePage.html
<div class="home-page">
Its home page
{{test}}
</div>
State
$stateProvider
.state('/', { //<-- here it should be some stateName rather than using `/`
url: '/',
templateUrl: 'myHomePage.html', //<--changed here
controller: 'mainController'
});
Plunkr

AngularJS routing is not working: no events on link clicks, no $routeParams

Somehow my app stopped working during development and I really cannot get what's wrong with it.
I've removed everything, the only code remaining is:
function handlerControl($scope, $routeParams, $location){
$scope.route = $routeParams;
}
var app = angular.module('Hello', []).config(
function($routeProvider){
$routeProvider.when('/:a/:b', {controller: handlerControl});
}
);
and html is
<body ng-app="Hello">
<div ng-controller="handlerControl">
{{route}}
</div>
</body>
omitting head part with including everything.
When I go to
http://helloday/#/a/b/
I'm getting an empty hash while expecting to get {a: 'a', b: 'b'}
What I'm doing wrong?
Bit modified(to make it work) jsFiddle: http://jsfiddle.net/wWDj2/http://jsfiddle.net/wWDj2/
Routing requires you use ngView, and that you specify either a template or a templateUrl:
App code.
var app = angular.module('myApp', []);
app.config(function($routeProvider) {
$routeProvider.when('/foo/:id', {
controller: 'FooCtrl',
template: '<h1>Foo {{id}}</h1>'
})
.when('/bar/:test', {
controller: 'BarCtrl',
templateUrl: 'bartemplate.html'
})
.otherwise({
controller: 'DefaultCtrl',
template: '<h1>This is the default</h1>'
});
});
app.controller('FooCtrl', function($scope, $routeParams) {
$scope.id = $routeParams.id;
});
app.controller('BarCtrl', function($scope, $routeParams) {
$scope.test = $routeParams.test;
});
app.controller('DefaultCtrl', function($scope){});
Your main page's markup:
<div ng-app="myApp">
Foo 123
Bar Blah
Default route
<hr/>
<div ng-view>
<!-- your processed view will show up here -->
</div>
</div>

AngularJS dynamic routing

I currently have an AngularJS application with routing built in.
It works and everything is ok.
My app.js file looks like this:
angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', { templateUrl: '/pages/home.html', controller: HomeController });
$routeProvider.when('/about', { templateUrl: '/pages/about.html', controller: AboutController });
$routeProvider.when('/privacy', { templateUrl: '/pages/privacy.html', controller: AboutController });
$routeProvider.when('/terms', { templateUrl: '/pages/terms.html', controller: AboutController });
$routeProvider.otherwise({ redirectTo: '/' });
}]);
My app has a CMS built in where you can copy and add new html files within the /pages directory.
I would like to still go through the routing provider though even for the new dynamically added files.
In an ideal world the routing pattern would be:
$routeProvider.when('/pagename', { templateUrl: '/pages/pagename.html', controller: CMSController });
So if my new page name was "contact.html" I would like angular to pick up "/contact" and redirect to "/pages/contact.html".
Is this even possible?! and if so how?!
Update
I now have this in my routing config:
$routeProvider.when('/page/:name', { templateUrl: '/pages/home.html', controller: CMSController })
and in my CMSController:
function CMSController($scope, $route, $routeParams) {
$route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
alert($route.current.templateUrl);
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
This sets the current templateUrl to the right value.
However I would now like to change the ng-view with the new templateUrl value. How is this accomplished?
angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/page/:name*', {
templateUrl: function(urlattr){
return '/pages/' + urlattr.name + '.html';
},
controller: 'CMSController'
});
}
]);
Adding * let you work with multiple levels of directories dynamically.
Example: /page/cars/selling/list will be catch on this provider
From the docs (1.3.0):
"If templateUrl is a function, it will be called with the following
parameters:
{Array.} - route parameters extracted from the current
$location.path() by applying the current route"
Also
when(path, route) : Method
path can contain named groups starting with a colon and ending with a star: e.g.:name*. All characters are eagerly stored in $routeParams under the given name when the route matches.
Ok solved it.
Added the solution to GitHub - http://gregorypratt.github.com/AngularDynamicRouting
In my app.js routing config:
$routeProvider.when('/pages/:name', {
templateUrl: '/pages/home.html',
controller: CMSController
});
Then in my CMS controller:
function CMSController($scope, $route, $routeParams) {
$route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
$.get($route.current.templateUrl, function (data) {
$scope.$apply(function () {
$('#views').html($compile(data)($scope));
});
});
...
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
With #views being my <div id="views" ng-view></div>
So now it works with standard routing and dynamic routing.
To test it I copied about.html called it portfolio.html, changed some of it's contents and entered /#/pages/portfolio into my browser and hey presto portfolio.html was displayed....
Updated
Added $apply and $compile to the html so that dynamic content can be injected.
I think the easiest way to do such thing is to resolve the routes later, you could ask the routes via json, for example. Check out that I make a factory out of the $routeProvider during config phase, via $provide, so I can keep using the $routeProvider object in the run phase, and even in controllers.
'use strict';
angular.module('myapp', []).config(function($provide, $routeProvider) {
$provide.factory('$routeProvider', function () {
return $routeProvider;
});
}).run(function($routeProvider, $http) {
$routeProvider.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
}).otherwise({
redirectTo: '/'
});
$http.get('/dynamic-routes.json').success(function(data) {
$routeProvider.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
});
// you might need to call $route.reload() if the route changed
$route.reload();
});
});
In the $routeProvider URI patters, you can specify variable parameters, like so: $routeProvider.when('/page/:pageNumber' ... , and access it in your controller via $routeParams.
There is a good example at the end of the $route page: http://docs.angularjs.org/api/ng.$route
EDIT (for the edited question):
The routing system is unfortunately very limited - there is a lot of discussion on this topic, and some solutions have been proposed, namely via creating multiple named views, etc.. But right now, the ngView directive serves only ONE view per route, on a one-to-one basis. You can go about this in multiple ways - the simpler one would be to use the view's template as a loader, with a <ng-include src="myTemplateUrl"></ng-include> tag in it ($scope.myTemplateUrl would be created in the controller).
I use a more complex (but cleaner, for larger and more complicated problems) solution, basically skipping the $route service altogether, that is detailed here:
http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm
Not sure why this works but dynamic (or wildcard if you prefer) routes are possible in angular 1.2.0-rc.2...
http://code.angularjs.org/1.2.0-rc.2/angular.min.js
http://code.angularjs.org/1.2.0-rc.2/angular-route.min.js
angular.module('yadda', [
'ngRoute'
]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/:a', {
template: '<div ng-include="templateUrl">Loading...</div>',
controller: 'DynamicController'
}).
controller('DynamicController', function ($scope, $routeParams) {
console.log($routeParams);
$scope.templateUrl = 'partials/' + $routeParams.a;
}).
example.com/foo -> loads "foo" partial
example.com/bar-> loads "bar" partial
No need for any adjustments in the ng-view. The '/:a' case is the only variable I have found that will acheive this.. '/:foo' does not work unless your partials are all foo1, foo2, etc... '/:a' works with any partial name.
All values fire the dynamic controller - so there is no "otherwise" but, I think it is what you're looking for in a dynamic or wildcard routing scenario..
As of AngularJS 1.1.3, you can now do exactly what you want using the new catch-all parameter.
https://github.com/angular/angular.js/commit/7eafbb98c64c0dc079d7d3ec589f1270b7f6fea5
From the commit:
This allows routeProvider to accept parameters that matches
substrings even when they contain slashes if they are prefixed
with an asterisk instead of a colon.
For example, routes like edit/color/:color/largecode/*largecode
will match with something like this
http://appdomain.com/edit/color/brown/largecode/code/with/slashs.
I have tested it out myself (using 1.1.5) and it works great. Just keep in mind that each new URL will reload your controller, so to keep any kind of state, you may need to use a custom service.
Here is another solution that works good.
(function() {
'use strict';
angular.module('cms').config(route);
route.$inject = ['$routeProvider'];
function route($routeProvider) {
$routeProvider
.when('/:section', {
templateUrl: buildPath
})
.when('/:section/:page', {
templateUrl: buildPath
})
.when('/:section/:page/:task', {
templateUrl: buildPath
});
}
function buildPath(path) {
var layout = 'layout';
angular.forEach(path, function(value) {
value = value.charAt(0).toUpperCase() + value.substring(1);
layout += value;
});
layout += '.tpl';
return 'client/app/layouts/' + layout;
}
})();

Categories