Setting dynamic parameters in URL with Angular UI Router - angularjs

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.

Related

Apollo Client 3 evict query result - doesn't work?

Using Apollo Client 3 and eed to remove all the results of a query regardless of the arguments. Tried like this;
cache.evict({
id: "ROOT_QUERY",
fieldName: "countries"
});
cache.gc();
However nothing removed from cache, __APOLLO_CLIENT__.cache.data still has all the result in the cache.
I can remove a single Country object on the other hand.
You can see it here sandbox
Simple adding broadcast: false parameter solved the problem;
cache.evict({
id: 'ROOT_QUERY',
fieldName: 'countries',
broadcast: false,
});
cache.gc();

Angular advanced searchbox lose focus after selecting suggested key-value per keyboard

I've implemented the angular-advanced-searchbox (with AngularJS 1.5.8, ui-bootstrap, JQuery) like the demo-page:
html
<nit-advanced-searchbox ng-model="searchParams" parameters="availableSearchParams" placeholder="Search..."></nit-advanced-searchbox>
script
$scope.availableSearchParams = [
{...},
{
key: "city",
name: "City",
placeholder: "City...",
restrictToSuggestedValues: true,
suggestedValues: ['Berlin', 'London', 'Paris'] },
{...}
];
};
Here is a Plunker of this implementation too. I'll refer to this example to picture my problem.
If I type 'city' in the searchfield and select it by hitting enter, then I'll see the suggested Value-List (Berlin, London, Paris) for about a second and then the focus 'll lost and the selected key-value (city) is automatically removed. It seems this won't happen, if the mouse pointer is rested over the search-input field (without any action).
With this issue, I can't use this module on my site - but I really want to :) Are any suggestions out there?
OK, this (low-level) fix worked for me - i've just commented line 107 ():
angular-advanced-searchbox-tpls.js [#107]
$scope.searchQueryChanged = function (query) {
// updateModel('change', 'query', 0, query);
};
This line is used to build 'pre-queries'. If you start typing 'city', the scope of searchParams generate a temporary query on the fly and would be changed to the selected key - g.E.:
{"query":"ci"}
This will then lead to a timeout after 'city' is selected. I don't know this 'query' is used for - all things 'll do their job furthermore. But by time I'll looking to a real fix for this problem :)

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.

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

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 ).

Backbone.js fetch method with data option is passing URL params with square brackets

I have the following code to fetch the data for my collection but with specifying what colors should come from the server:
fruits = new FruitsCollection();
fruits.fetch({
data: {color: ['red', 'green']}
});
This is what I expect:
http://localhost:8000/api/fruits/?color=red&color=green
This is what I got:
http://localhost:8000/api/fruits/?color[]=red&color[]=green
As you can see, for some unknown reason Backbone.js is appending the square brackets to the URL params, instead of having color=green I have color[]=green
I'm using django-rest-framework in the server side and I know I can do a hardcoded fix there, but I prefer to know the logic reason because it is happening and how can I solve it from my javascript.
Backbone uses jQuery.ajax under the hood for the ajax request so you need to use the traditional: true options to use "traditional" parameter serialization:
fruits = new FruitsCollection();
fruits.fetch({
traditional: true,
data: {color: ['red', 'green']}
});

Resources