Build link with parameter (?key=val) with ui-sref directive - angularjs

I'm using Angular ui-router, my state look like:
.state('detail', {
url: '/detail/{id}',
In the HTML file I prefer to use ui-serf directive to build the link. For example:
<a ui-sref="detail( { id:123 } )">...
How can I build a link with optional query parameter? For example:
/detail/123?mode=json&pretty=true

I think that the ui-router way it's not to use query parameters, but instead of doing:
/detail/123?mode=json&pretty=true
declare the state as
.state('detail', {
url: '/detail/{id}/{format}/{pretty}',
...
and using it like:
/detail/123/json/true
Anyway, if you really want to use the query format, you can do it out-of-the-box like as state in the doc:
You can also specify parameters as query parameters, following a '?':
url: "/contacts?myParam" // will match to url of
"/contacts?myParam=value" If you need to have more than one, separate
them with an '&':
url: "/contacts?myParam1&myParam2" // will match to url of
"/contacts?myParam1=value1&myParam2=wowcool"
See: https://github.com/angular-ui/ui-router/wiki/URL-Routing#query-parameters

Have you tried just adding it? :
<a ui-sref="detail( { id:123, optional: 'moo' } )">...
I know that is how dotJEM angular routing would work ( except the syntax is a bit different ).

Related

UrlMatcher matches route with parameter when parameter does not exist (not like in the documentation)

I have two very simple routes (among others):
.state("master", {
abstract: true,
url: "/{tenantName}",
...
})
.state("default", {
url: "",
...
})
This is from the documentation:
'/user/:id' - Matches '/user/bob' or '/user/1234!!!' or even '/user/'
but not '/user' or '/user/bob/details'. The second path segment will
be captured as the parameter 'id'.
So now if I go to www.myserver.com I exect the second route to kick in, because according to documentation it should not match the direct url, but in fact it does and causes me lots of troubles. Am I doing something wrong?
P.S. I want www.myserver.com go to second route and www.myserver.com/tenant1 to go to first route.

Setting dynamic parameters in URL with Angular UI Router

I am using query system which allows user to construct query from list of dynamic fields and I want to persist query in URL.
Normally I would do:
$stateProvider.state('alerts', {
url: '/alerts/list?p1&p2&p3'
})
and in controller I could read params with $stateParam:
console.log($stateParams.p1)
I could save query in URL by:
$state.go($state.current, {p1:'1', p2: '2'}, {location: true, inherit:true, notify:false})
But the problem is I cannot declare all params.
I would like to do:
$state.go($state.current, {p1:'1', p2: '2', p3:'3', p4: '4', p5:'5'}, {location: true, inherit:true, notify:false})
but ui-router ignores params that are no declared for state.
I know $location.search gives me access to URL search part but how can I set URL (without changing state and reloading page)?
This worked for me:
$stateProvider.state("alerts", { url: "/alerts/list?{query:json}" });
and
$state.go($state.current, {query: {a:1, b:2, c: '3'}}, {location: true, inherit:true, notify:false})
Make sure you are using the latest 1.x ui-router - this is important. Then in your route, use the dynamic: true in the parameter settings. This will prevent refreshing. Use the ui-sref as you normally would - don't use any of that notify/reload/location stuff at all as it will break things - dynamic takes care of setting those properly in the background. With value you can set a default one, and squash removes the trailing slash in the URL if it's empty (set to '' - not null).
.state('myappstate.somestate', {
url: '/:a/:b/:c/:d',
params: {
a: {dynamic: true, value: 'someDefault'},
b: {dynamic: true, value: 'anotherDefault'},
c: {dynamic: true, value: '', squash: true},
d: {dynamic: true, value: '', squash: true}
}
})
There is a very long discussion going back to 2013 on one of angular-ui's Github issue pages. So far no answer given has satisfied everyone, and I'm one of the unsatisfied people.
So far the best workaround is to use query parameters only (not url path parameters) and add the reloadOnSearch: true option to states you plan to use dynamic query parameters on (changing them without reloading the page). That's discussed in a different StackOverflow answer here.
As of the day I'm writing this, there is a branch of angular-ui with something called "dynamic parameters" which is now 300 commits behind master but might have solved the problem (but now it's far enough behind master that I don't want to use it). There is also an upcoming 1.0 version of ui-router but I do not know when that will be released.

UI Router Prefix

For example you site is hosted on "http://www.domain.com". And you have a products page defined by the url below:
http://www.domain.com/products
Is it possible to define a prefix? Moreover, I want the prefix to have a parameter as well. I would define the products page for different shops using the urls below, where "shop/x" is the prefix with the parameter "x":
http://www.domain.com/shop/1/products
http://www.domain.com/shop/2/products/1
Yes, just use a .state config along the following lines
.config(function($stateProvider) {
return $stateProvider.state('main', {
url: '/shop/:shopID/products/:productID',
...
});
and then in your controller you can refer to $scope.shopID and $scope.productID just as you would expect to.

Specify locale id in url

I can find very little about this specific subject of angularJS.
How can I specify and rewrite all urls with a locale id, like en-uk, nl-nl?
I also want to use proper routing to automate the process and providing the locale id to the corresponding controllers.
A few examples:
/#!/en-uk/home ---> Use of controller Home and provide the locale id en-uk
/#!/nl-nl/home ---> Use of controller Home and provide the locale id nl-nl
/#!/en-uk/shop ---> Use of controller Shop and provide the locale id en-uk
/#!/nl-nl/shop ---> Use of controller Shop and provide the locale id nl-nl
Question: How is this done in angularJS?
You can configure the $routeParams to have the locale as the first section:
$routeProvider
.when("/:local/home", { controller: "HOME_CONTROLLER" ... })
.when("/:local/shop", { controller: "SHOP_CONTROLLER" ... })
Here's the documentation on it: http://docs.angularjs.org/api/ngRoute.$routeParams

Backbone routing regex

Trying to get my head around sorting this routing regex out, so:
'quotes(/:action)': 'quotes',
'quotes/:id(/:params)': 'quotesEdit'
Two URLs:
http://domain.com/#quotes/action=showModal
http://domain.com/#quotes/123
My question:
How can I make sure that the URL with the action= matches on the first Route, but not the second? and for urls like quotes/123 to fall through to the second Route?
try to add routes directly via router`s initialize
initialize: function(options) {
this.route(/^quotes\/([0-9]+)$/, "ids");
this.route(/^quotes\/action=(.*)$/, "act");
},
ids: function(id){
alert('id='+id);
},
act: function(act){
alert('act='+act);
},
You can make this work by over-riding Backbone.history.loadUrl with your special-cases. Essentially, you would be skipping matched routes based on the url parameters...but that seems awfully hack-ish.
An option is to declare a single route and branch on the arguments:
'quotes(/:id)(/:params)': 'quotes'
quotes:function(id,params) {
if (id && id.match(/^\d+$/)) { // if id is a number
this.quotesEdit(id,params);
}
else {
// your quotes logic
}
Instead of the above, you may want to look into changing your routes a bit and your problem is longer an issue.
'quotes(/:action)' : 'quotes',
'quotes/edit/:id(/:params)' : 'quotesEdit'

Resources