Angular JS 'route' doesn't match component with %2F (encoded '/') - javascript

I have a 'route' in Angular JS as follows
$routeProvider.when('/foos/:fooId', { controller: FooController, templateUrl: 'foo.html'});
and it works great, unless the :fooId component contains either a '/' or '%2F' (encoded form)
How can I make this work, my 'fooId' can contain /s ?

You can't easily do this because if you use a link with %2F in it, the browser will just decode it for you and it'll end up being /. AngularJS currently doesn't allow you to use / in $route params.
You can double encode it, like in this plnkr: http://plnkr.co/edit/e04UMNQWkLRtoVOfD9b9?p=preview
var app = angular.module('app', []);
app.controller('HomeCtrl', function ($scope, $route) {
});
app.controller('DirCtrl', function ($scope, $route) {
var p = $route.current.params;
$scope.path = decodeURIComponent(p.p1);
});
app.config(function ($routeProvider) {
$routeProvider
.when('/', {templateUrl: 'home.html', controller: 'HomeCtrl'})
.when('/dir/:p1', {templateUrl: 'dir.html', controller: 'DirCtrl'})
.otherwise({redirectTo: '/'});
});
And the link would be: click here.
Another option, if you have a set number of / characters in your parameters can be found here: How can I make the angular.js route the long path

Based on the answer of Langdon, I created a filter which encodes everything twice, and another one which decodes:
.filter('escape', function() {
return function(input) {
return encodeURIComponent(encodeURIComponent(input));
};
})
.filter('unescape', function() {
return function(input) {
return decodeURIComponent(input);
};
});
I use this in my product links as follows:
<a href="#/p/{{product.id}}/{{product.name | escape}}">
On the product page, I decode the product name:
<h1>{{product.name | unescape}}</h1>

You need not to encode anything here. Just add * in your path Param as mentioned below and enable html5Mode
app.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/home', {templateUrl: 'home.html', controller: 'HomeCtrl'})
.when('/base/:path*', {templateUrl: 'path.html', controller: 'pathCtrl'})
.otherwise({redirectTo: '/home'});
});
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});

include
$locationProvider.hashPrefix('');
in your config.

Related

Angular $routeParams empty object

I'm trying to get a query value from my url using angular's routeParams.
I've included angular-route in my html page:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-route.min.js"></script>
Included Ng-Route in my app:
var app = angular.module('app', [
'ngRoute',
'reportController'
]);
And set up my controller as following:
var reportController = angular.module('reportController', []);
reportController.controller('CandidateCtrl', ['$scope', '$routeParams',
function($scope, $routeParams) {
console.log(JSON.stringify($routeParams, null, 4));
$scope.person = $routeParams.person;
}]);
When I access the following URL, however, routeParams is an empty object: {}.
http://localhost:8080/report?person=afe75cc7-fa61-41b3-871d-119691cbe5ad
What am I doing wrong?
Edit:
I've configure the possible route - my routeParams object is still coming up null. I've tried:
famaApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/report:person', {templateUrl: 'Report.html', controller: 'CandidateCtrl'});
}]);
and
when('/report?person', {templateUrl: 'Report.html', controller: 'CandidateCtrl'});
Rather then accessing like
http://localhost:8080/report?person=afe75cc7-fa61-41b3-871d-119691cbe5ad
try to access it like
http://localhost:8080/#/report/afe75cc7-fa61-41b3-871d-119691cbe5ad
you will get the guid in $route.Params
You have to set your routes to receive the arguments you want with $routeProvider..
Example:
app.config(['$routeProvider', '$locationProvider' function ($routeProvider, $locationProvider) {
$routeProvider
.when('/',
{
templateUrl: 'someHtmlUrl',
controller: 'someController',
controllerAs: 'someCtrl',
caseInsensitiveMatch: true
})
.when('/:person',
{
templateUrl: 'someHtmlUrl',
controller: 'someController',
controllerAs: 'someCtrl',
caseInsensitiveMatch: true
})
.otherwise(
{
templateUrl: 'someHtmlUrl'
});
$locationProvider.html5Mode(true); //Use html5Mode so your angular routes don't have #/route
}]);
Then you can just do
http://localhost:8080/afe75cc7-fa61-41b3-871d-119691cbe5a
And the $routeProvider will call your html and your controller as you can see with the .when('/:person'.. and then you can try and access your $routeParams and you will have your person there, $routeParams.person.

pass a variable into $routeProvider in angular between views? - angularjs

Wondering if there's an 'angular specific' way to try and achieve this.
I have a page with some views. When a user clicks an anchor, the views change, simple enough. What I'm curious is, if when the user clicks, is it possible to store a variable (say the span) then pass it to the $routeProvider to load the content a bit more dynamically?
so for anchor tag #name1, when that view is displayed, I can pass "name1" into nameHolder as a variable to load some files with same name.
HTML
<span>name1</span>
JS
var nameHolder = [];
var sampleApp = angular.module('sampleApp', ['ngRoute']);
sampleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/' + nameHolder, {
templateUrl: 'templates/individkcd.html',
controller: 'individ',
nameofuser: nameHolder
}).
when('/', {
templateUrl: 'templates/home.html'
});
}]);
sampleApp.controller('individ', function($scope, $route) {
$scope.img = $route.current.nameHolder;
});
Thanks for any info.
UPDATED:
Solution at new thread.
angular js - passing a variable into $routeProvider
You need to add the parameter to your $routeProvider template:
sampleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/' + nameHolder, {
templateUrl: 'templates/individkcd/:nameHolder',
controller: 'individ'
}).
when('/', {
templateUrl: 'templates/home.html'
});
}]);
Then in your target controller use $routeParams:
sampleApp.controller('individ', function($scope, $routeParams) {
$scope.img = $routeParams.nameHolder;
});
From the $routeProvider docs linked above:
path can contain named groups starting with a colon: e.g. :name. All
characters up to the next slash are matched and stored in $routeParams
under the given name when the route matches

Routes fetched from controller

is it possible to load url from controllers in routeProvider?
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/LALA', {
controller: 'LalaController',
templateUrl: '/mlala.html'
})
.when('/HOHO', {
controller: 'HohoController',
templateUrl: '/hoho.html'
})
.otherwise({redirectTo: '/'});
and I would like something like this:
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/MO', {
controller: 'MOController',
templateUrl: $scope.url
})
.when('/MOCache', {
controller: 'MOCacheController',
templateUrl: $scope.url
})
.otherwise({redirectTo: '/'});
Route URLs would be defined in Controllers.
Well, no.
But you can use named groups, assign a function to templateUrl and get the route parameters passed in:
.when('/MO/:page', { // <-- ':page' is a named group in the pattern
controller: 'MOController',
templateUrl: function (params) {
// use the route parameters to return a custom route
return 'views/partials/mo/' + params.page + '.html';
}
})
Than you can just inject whatever custom parameter you like in your views, e.g.:
<!-- 'paws' and 'whiskers' will be passed to the route params -->
paws page!
whiskers page!
Look, mommy, no controllers!
Reference
$routeProvider on the AngularJS docs.

How can I make the angular.js route the long path

I am making a file explorer with angular.js.
so, I will deal with some long url,
eg:
mydomain/folder1/sub1/grand-sub1/.././
I just learn angular and find out that angular has the $routeProvider, but, it seems I should write lots of "when" to make this work (the template will not used if I don't define the "when").
does angular support "*" to make all of the sub dir's paths use the same template?
or, does any other method to handle this? Thx.
Since $routeProvider doesn't currently support wildcards (see here and the 2 links in the answer), you have to hack it up a little...
http://plnkr.co/edit/OuVRSrDUvdVF5yFDHnmM?p=preview
HTML
/
<br/>
/folder1
<br/>
/folder1/sub1
<br/>
/folder1/sub1/grandsub1
<br/>
JavaScript
app.controller('DirCtrl', function ($scope, $route) {
var p = $route.current.params;
$scope.path = '/';
if (p.p1) $scope.path += p.p1;
if (p.p2) $scope.path += '/' + p.p2;
if (p.p3) $scope.path += '/' + p.p3;
if (p.p4) $scope.path += '/' + p.p4;
if (p.p5) $scope.path += '/' + p.p5;
});
app.config(function ($routeProvider) {
$routeProvider
.when('/', {templateUrl: 'home.html', controller: 'HomeCtrl'})
.when('/dir', {templateUrl: 'dir.html', controller: 'DirCtrl'})
.when('/dir/:p1', {templateUrl: 'dir.html', controller: 'DirCtrl'})
.when('/dir/:p1/:p2', {templateUrl: 'dir.html', controller: 'DirCtrl'})
.when('/dir/:p1/:p2/:p3', {templateUrl: 'dir.html', controller: 'DirCtrl'})
.when('/dir/:p1/:p2/:p3/:p4', {templateUrl: 'dir.html', controller: 'DirCtrl'})
.when('/dir/:p1/:p2/:p3/:p4/:p5', {templateUrl: 'dir.html', controller: 'DirCtrl'})
/* add more as necessary */
.otherwise({redirectTo: '/'});
});
Don't repeat yourself!
var dirRoute = {templateUrl: 'dir.html', controller: 'DirCtrl'};
$routeProvider
.when('/', {templateUrl: 'home.html', controller: 'HomeCtrl'})
.when('/dir', dirRoute)
.when('/dir/:p1', dirRoute)
.when('/dir/:p1/:p2', dirRoute)
.when('/dir/:p1/:p2/:p3', dirRoute)
.when('/dir/:p1/:p2/:p3/:p4', dirRoute)
.when('/dir/:p1/:p2/:p3/:p4/:p5', dirRoute)
Starting in AngularJS 1.2 (currently in release candidate phase), you can use wildcards to match more of a path. From the new documentation:
path can contain named groups starting with a colon and ending with a star (:name*). All characters are eagerly stored in $routeParams under the given name when the route matches.
For example, routes like /color/:color/largecode/:largecode*\/edit will match /color/brown/largecode/code/with/slashs/edit and extract:
color: brown
largecode: code/with/slashs.
It's worth nothing that you now have to include the extra angular-route.js file, as the routing layer is no longer included by default to save file size. Furthermore, your module must declare ngRoute as one of its dependencies. Your code would look like this:
var app = angular.module('app', ['ngRoute']);
app.controller('HomeCtrl', function ($scope, $route) {
});
app.controller('DirCtrl', function ($scope, $routeParams) {
$scope.path = '/' + $routeParams.dir;
});
app.config(function ($routeProvider) {
$routeProvider
.when('/', {templateUrl: 'home.html', controller: 'HomeCtrl'})
.when('/dir/:dir*', {templateUrl: 'dir.html', controller: 'DirCtrl'})
.otherwise({redirectTo: '/'});
});
Working example: http://plnkr.co/edit/BSPWYPnHM7GJRgNCAjoi?p=preview

Catch all route parameter

I have a url such as this: http://foo.bar/#/some/other/path
How do I capture "some/other/path" as a route parameter?
I tried this:
var App = angular.module("App", [])
.config(function($routeProvider){
$routeProvider
.when('/:path', { controller: ListCtrl, templateUrl: 'list.html'})
.otherwise({ redirectTo: '/'})
});
But :path is only giving me some rather than some/other/path
As mentioned by Stewie in the comment above, Angular unstable 1.1.3 now supports catch-all by using an asterisk.
For example:
var App = angular.module("App", [])
.config(function($routeProvider){
$routeProvider
.when('/*path', { controller: ListCtrl, templateUrl: 'list.html'})
.otherwise({ redirectTo: '/'})
});
Partial string matches—-such as matching for instances of jpg in a url—-still don't seem supported.

Categories