Use slash inside hash with %2F - angularjs

I'm having the following routes:
window.m.config( ['$routeProvider',($routeProvider) ->
$routeProvider
.when('/player/:index', {
templateUrl: 'view.html',
controller: 'View'
})
.when('/', {
templateUrl: 'list.html'
controller: 'List'
})
]
)
Some of my players have a / inside their name. So I am decoding it eg, for a player named a/b, the url to that player will be /player/a%2Fb
However, when I do the following, the hash will change when I load my app, so that it becomes /player/a/b.
This makes the page not load for that particular player.
If I put a hash with %2F in a non-angular app, the %2F is not transformed into / so it is not the browser that is inducing the error. However, if I then try to get the hash, I still get /player/a/b , where the encoded slash is === to the other slashes.
How should I handle slashes inside the variable values of my routes ?

You have to add
*
at the end of your route. So in your case:
'/player/:index*'
That should work also with Angullar 2+. Check
Github issue.

I would replace/escape the slashes with underscores when creating the route argument and then re-inserting them in the controller - this way you avoid the differences.

So I just found this on github and wanted to provide a temporary fix, in my application I noticed it would only route on params that were double encoded so for example I used this as a temp work around:
encodeURIComponent(encodeURIComponent("this/string/is/a/param/"))
This seemed to work for me.

Related

$routeProvider.when('/', ...) has no effect, when html5 mode is on

Solution to the problem: url you write in base tag should have a trailing slash.
I have the following routes configuration, but template is not requested, if html5 mode is on. No errors, no attempts to get the resource from the server.
Neither changing base url, nor setting prefix with hasPrefix('!') has no effect on this behavior
angular
.module('beneficiaryBanks')
.config(configRoutes);
configRoutes.$inject = ['$routeProvider','$locationProvider'];
function configRoutes($routeProvider, $locationProvider) {
$routeProvider
.when('/',
{
controller: 'beneficiaryBanksListController',
controllerAs: 'listVM',
templateUrl: 'BeneficiaryBanksList.cshtml'
});
$locationProvider.html5Mode(true);
}
It looks like angular does not match current url with '/'.
update 1
Debugging shows that for url http://localhost:8080/APS/Home/BeneficiaryBanksModule and base address APS/Home/BeneficiaryBanksModule angular sees route as /BeneficiaryBanksModule which does not match with /, whereas route becomes just a / when html5 mode is disabled.
As I could see here, there are some configurations that you may have to do in order to achieve this combination of AngularJS and IIS Express with html5 mode activated.
I don't know if you read this article, but there are a few tips to make it work.
That's because your request is handled by server itself, but not by your angular app.
Try to read some articles about how to setup your server to work with html5 mode:
https://dzone.com/articles/fixing-html5mode-and-angular
http://www.thinkovator.com/blog/post/angularjs-html5-mode-and-iis-rewrite/
Hope, it will help.
The problem was in base tag. If it does not end with slash / angular treats last part as a file name and drops it.
That's why I saw /BeneficiaryBanksModule instead of /

Dynamic nested routing in angularJs

Trying to implement the following route system with angular stateProvider:
some_domain.com/abc/pqr/xyz
Issue is the number of levels after "some_domain.com" can vary. It can be like
some_domain.com/abc/pqr/xyz
some_domain.com/abc/pqr
some_domain.com/abc
some_domain.com/abc/pqr/xyz/1234
tried the many approaches for this in the state definition:
$stateProvider
.state('dummy', {
url: '/*',
templateUrl: 'views/home.html',
controller: 'LandingPage'
});
}]);
Can anybody help me regarding this?
As the parameters you are talking about are part of the route itself, so you cannot have a single route to handle all these cases. I can think of 2 ways to go about it :
Create a seperate route for each case.
Use optional parameters if you can modify the logic accordingly. If the parameters can be optional, they should sent as query parameters instead of making them part of URL as such. So, the URL becomes something like :
url: '/dummy?param1?param2?param3'

Create Angular Dynamic Route

I have a route string like the following var global_book_route = /books/:id specified in a variable.
I want to be able to use $route or $location to deep link to this route in a controller, is there a way to do this without re-specifying the url prefix?
This would work: var id=1; $location.path('books/'+id') -> '/books/1'
However, this does not: $location.path(global_book_route).search({id:1}) -> 'books/:id?id=1'
Is there a way I can use the route specified in the string to go to the correct location?
I think you are mixing up the route itself (/books/:id) with the representation of the route in your code.
For example, your global_book_route should be only "/books/".
Then, if you want to load a specific book, you can go the the location global_book_route + book_id as long as the route is declared in your code, like:
$routeProvider
.when('/Book/:bookId', {
templateUrl: 'book.html',
controller: 'BookController',
resolve: {
}
})
On a side node, when dealing with routes in Angular, it's really worth it to look into angular-ui, the ui-router offers a way better system to manage your routes and states.

ui-router url params with a hierarchy

how is it possible to set up url routes in the $stateProvider of the ui-router module with url params in a hierarchy like this
/home
/:username
/:title/editor
I only get it to work if there is no conflict on the same hierarchy level like:
/home
/user/:username
/editor/:title
Right now everything will router to /home if I try to set it up like in the first example.
I know it from other situations like on Google Appengine, where the first approach would work aswell and where it would be seen as a kind of hierarchy, where the /:username route would apply as long it not equals 'home'.
Thanks for help!
I would say this should be possible, e.g. this would work (see example):
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'test.html',
controller: 'TestCtrl',
})
.state('editor', {
url: '/:title/editor',
...
})
.state('user', {
url: '/:userName',
...
Observe it here. The reason why this is working, because the state editor - with a strong key /editor is evaluated before userName. The same for home - it is the first evaluated pattern.
BUT - I would suggest, do not count on order. Use these discriminators at the beginning (e.g. /user/... or /editor/..). Our users, will understand it as well, and any later confusion (why this url triggered that state) won't surprise us

Multiple optional parameters in Angular.js

I typically use querystrings for filtering results, eg:
URL: /Events/List?type=art&city=miami&life=present
I can put them in any order and get the same results, eg:
URL: /Events/List?city=miami&life=present&type=art
URL: /Events/List?life=present&type=art&city=miami
I can also make them optional, eg:
URL: /Events/List?type=art,
or: /Events/List?type=art&life=&city=
Question: How can I achieve this same "effect" with Angular.js routes? given the fact that parameters are passed all in a "RESTful" way in Angular
I was thinking in something like this:
URL: /Events/List/city/miami/life/present/type/art
Which I can achieve with a route like this:
.when('/Events/List/city/:city?/life/:life?/type/:type?', { ... }
But I already see many problems:
Order of parameters is important (I would have to define many times the route?)
Optional parameters will give a non intuitive URL,
eg: /Events/List/city/life/type/art,
and this is not the case in optional querystrings (they are more intuitive to read I think): eg: /Events/List/?city=&life=&type=art
If you want to use query strings angular has $location.search() that is both a setter and getter.
The difference between angular search and window version location.search is the query falls after the url hash and when setting or getting it uses objects rather than strings
See Using $location in developer's guide
You can inject $routeParams into your controller. Here's an example from the docs:
// Given:
// URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
// Route: /Chapter/:chapterId/Section/:sectionId
//
// Then
$routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
http://docs.angularjs.org/api/ngRoute.$routeParams
I recently encountered a similar need (the ability to grab an unknown quantity of arguments off the path), and had started off by looking at $routeProvider. I ultimately abandoned that effort in favor of ui.router.
The most powerful (but possibly also tedious) approach for you would be to work with regex parameters. Consider the following (a snippet from some code I'm currently authoring):
$stateProvider
.state("list", {
url: "/",
controller: "PluginsListController",
templateUrl: "PluginsList.html"
})
.state("path", {
url: "/{plugin}/*path",
controller: "PluginDetailsController",
templateUrl: "PluginDetails.html"
})
;
The second state accepts two positional parameters: a plugin and a path. The path argument is a wildcard, that grabs everything after the immediately preceding slash. The idea here is that I can specify something like http://www.myfirsturl.com/app/MyFirstPlugin/level1/level2/level2.php, and end up with "MyFirstPlugin" in $stateParams["plugin"] and "level1/level2/level2.php" in $stateParams["path"]. It's up to the application logic to handle the long path parameter (and you would be likewise responsible for consuming this variable-length argument), but this approach does allow you to write a single state handler for an unknown number of url paths.

Resources