How to create AngularJS Route with dashes instead of slashes - angularjs

Is it possible to create Angular routes with dashes instead of slashes, and variable content in the URL fragment? For example:
In the Angular phone Tutorial, URLs look like this, e.g:
http://angular.github.io/angular-phonecat/step-11/app/#/phones/motorola-xoom
this is implemented via a Route Provider such as:
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: 'PhoneDetailCtrl'
})
what I'd like to do is have URLS that look more like:
http://angular.github.io/angular-phonecat/step-11/app/#/phones/{{manufacturer}}--{{devicename}}--{{phoneid}}
where {{phoneid}} is a numerical database key and the {{manufacturer}} text will vary from phone to phone. This is because I need the numerical key to drive my database but want the manufacturer & devicename text (or my equivalent) in the URL for seo purposes....
Effectively I'd like to do in Angular Routes what I can do in htaccess files, where I'd do something like:
RewriteRule ^(.)--by--(.)--(.*)$ phone.php?mfg=$1&devicename=$2&phoneid=$3
I know Angular routes don't support wildcards like this, but wondering how I might be able achieve an effect somewhat like this. Or maybe there is some extension which enables this?

You can use variable using :name in the url (source)
In your config:
config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/phones/:manufacturer--:devicename--:phoneid', {
templateUrl: 'file.html',
controller: 'PhoneController'
});
To access the parameters in your controller:
$routeParams.manufacturer
$routeParams.devicename
$routeParams.phoneid

Related

How do I parse the location path in AngularJS?

For example the page is 'http://mywebsite/details/555', how can I get that '555' out of there in my controller? It's not a parameter, so I cannot look up for it by name.
Have a look at the Angular routing parameters. The number you want is actually and id used in the routing path which you can catch:
https://angular.io/guide/router
https://angular-2-training-book.rangle.io/handout/routing/routeparams.html
Your are writing that 555 is not a parameter - but I think you want to use it like a parameter. Parameters look like: http://mywebsite/#/details/555
You can then define this in your router (here I'm using ui-router, but you can do the same with ng-route:
$stateProvider
.state('details.id', {
url: "/details/:id",
templateUrl: 'detail.html',
controller: myController
})
See https://github.com/angular-ui/ui-router/wiki/URL-Routing
If you still want to parse your URL string, you can do it this way:
var detailId = this.href.substr(this.href.lastIndexOf('/') + 1);
But the right (and probably the only working) way is to use the router for that.

How to resolve similar variables in $routeProvider?

For the following case :
$routeProvider
.when('/:city/:locality', {
controller: 'controller1'
})
.when('/:state/:city', {
controller: 'controller2'
});
Is there any way to distinguish between the two URLs on front-end to serve different controllers? For sake of scalability, please assume there can be other cases of similar variable URLs.
Edit: I cannot append constants in route because of SEO purposes.
Those 2 routes are exactly the same. They state that there are 2 path params that are dynamic.
You would neednto have something staric in the path for the route to know what your are trying to do.
Such as
/city/:city/:locality
And
/state/:state/:city

How to structure ui-router to have SEO friendly url structure

I am facing a url structure problem using ui-router in AngularJS. I want to have first level SEO friendly url structure like this:
https://people-profile.com/mike-david-tringe
So I can grab the SEO name "mike-david-tringe" via stateParam and use it to find data in database and populate the page.
The $stateProvider has code like this:
$stateProvider
.state('people', {
url: '/:nameUrl',
templateUrl: 'app/frontend/page.tmpl.html',
params: {
nameUrl: {squash: true},
},
controller: "PageController",
controllerAs: 'vm'
})
.state('admin', {
url:'/admin/:userId',
templateUrl:'app/frontend/admin/admin.html',
controller:'AdminController',
controllerAs: 'admin'
})
With above code, I can have https://people-profile.com/mike-david-tringe working with nameUrl = mike-david-tringe and I got SEO friendly first level url link. mike-david-tringe is SEO friendly and most important keywords beside the domain name.
But with this structure, https://people-profile.com/admin/ or https://people-profile.com/login/ will not work now. Since my controller try to grab admin as nameUrl and looking for data. And admin is not a nameUrl so my database will return null, the app will fail.
In short, stateParam nameUrl will grab anything after "/" so the url setting will think admin and login is :nameUrl but in fact, it is not.
So how do I structure my app ui-router structure to have SEO friendly url like https://people-profile.com/mike-david-tringe but when url is https://people-profile.com/admin/, it will load admin.html template and use AdminController instead as I defined in $stateProvider?
All you need to do is swap the order of them. The router will check in order of definition, so if /:nameUrl comes before /admin it will trigger first. But if you put /:nameUrl last then it will trigger on any url that hasn't already triggered something above.
A word of warning however. Moving between two urls that trigger the same state (like two urls that both hit /:nameUrl in your case) will not reload the controllers on the page. Only changing state will do that. There are options to change this behaviour, but it has always been very buggy for me.

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.

Dynamic route params in AngularJS

I am familiar with angularjs
When I want to add my routing to my application I use $routeProvider
In $routeProvider.when(), I define routes.
How to define a route If I have a directory browser like structure like:
http://myfolderbrowserapp.com/:folder1/:folder2/.../:folderN
Is it possible with angularjs like:
$routeProvider.when('/**', {
template:'template'
})
Is this possible with angular routing? If not is there a workaround?
Please help
From $routeProvider docs
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.
So you could define
$routeProvider.when('/:folders*', {
template:'template'
})
And then (in controller e.g.)
$rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
if (angular.isDefined($routeParams.folders))
var foldersArray = $routeParams.folders.split('/');
});
However the path definition /:folders* is too generic and would probably be matched even in cases when you do not want to (don't know how your other paths look like).

Resources