Parameters in URL using Angular's UI-Router, issue with .otherwise - javascript

I want to search on my page. Actually, my code is
$stateProvider
.state('aaa', {
url: '/aaa',
templateUrl: 'client/parties/views/aaa.ng.html',
controller: 'Aaa'
})
$urlRouterProvider.otherwise("/default");
And now, I want to search on my page, but the params MUST working with the URL.
How to use params when I have $urlRouterProvider.otherwise?
Actually, everything after /aaa/ in URL causes redirect to /default.
Important thing: I have more than 20 parameters, but when there're not selected, I don't want to pass it via URL. This is important because I think I can't do something like url: '/details/:param1:param2:param3:param4',
Can you help me?

Looking at the documentation for ui-router, it doesn't seem like it is possible to not have it redirect without having at least one parameter defined on the state's route.
To accomplish what you want, I think the best is to use a catch all parameter of some sort. It's either that, restricting deep-linking, or reducing the amount of parameters and manually defining it.
Define a catch all parameter as shown below. In this case the parameter is path redirects will not take place if there is nothing after "/files/":
'/files/{path:.*}' - Matches any URL starting with '/files/' and captures the rest of the path into the parameter 'path'.
'/files/*path' - Ditto. Special syntax for catch all.
Define one parameter on a new route, and then split the one parameter into multiple parameters in the controller.

Related

Removing query string parameter from Url

Coming from AngularJS I thought this would be easy enough in Vue.js 2 as well. But it seems this is difficult by design in Vue.
In AngularJS I can do this $location.search('my_param', null); which will effectively turn https://mydomain.io/#/?my_param=872136 into https://mydomain.io/#/.
In Vue I have tried this.$router.replace('my_param',null);, but it will only do https://mydomain.io/#/?my_param=872136 -> https://mydomain.io/#/my_param, leaving the empty my_param.
IsnĀ“t there anyway in Vuejs2 to remove the query params from the Url? Should I resort to plain JS to achieve this?
router.replace() is to navigate by removing the current URL from the browser history stack and replace it with the argument route you pass to it.
The actual syntax is router.replace(url_location, onComplete, onAbort).
What you are doing is router.replace(my_param, null) which is removing the current URL from the history stack and replacing it with 'my_param' and for the onComplete callback you are passing a null
So do it like this:
this.$router.replace('/')
More info on programatic navigation
In the case that you have multiple query parameters the correct way to remove one of them would be:
const query = Object.assign({}, this.$route.query);
delete query.my_param;
this.$router.replace({ query });
#DaveIdito's answer given in a comment above has been valuable to me several times. Adding it as an answer in order to bring proper attention to it.
To only remove all of the the query params without loading again or changing history, use:
this.$router.replace({'query': null});
This worked for me pretty well. It replaces all the query parameter and just changes the route to path only.
router.replace(route.path);

Conditional "otherwise" routing in Angular

I'm familiar with the "$urlRouterProvider.otherwise('{route here}')" syntax in angular to use as catch all in Angular UI-Router.
What I'm wondering is - is there a way to do conditional "otherwise" routing based on the parent state of when the route is entered incorrectly?
For instance, suppose that I have the following configuration:
$stateProvider
.state('core', {configuration here})
.state('core.page1', {configuration here...})
.state('dashboard', {configuration here})
.state('dashboard.page1', {configuration here})
$urlRouterProvider.otherwise('/core/page1');
What I'd like to have happen is that anytime a route is entered in that has "/core/{route here}",
if it doesn't match any of the current states, to route back to '/core/page1',
and anytime a route is entered that has "/dashboard/{route here}" that doesn't match any of the current states, to route back to "/dashboard/page1".
Anyone have experience doing this, or an idea of how I could accomplish it? Is there anything built in to Angular that allows for this type of behavior?
Thanks in advance!
As shown here
How not to change url when show 404 error page with ui-router
The .otherwise() does not have to be a string (url)... it could be a smart decision maker:
$urlRouterProvider.otherwise(function($injector, $location){
var state = $injector.get('$state');
if(....)
state.go('core');
else(...)
state.go('dashboard');
...
return $location.path();
});
The doc:
$urlRouterProvider.otherwise(rule)
Defines a path that is used when an invalid route is requested.
string - The url path you want to redirect to or a function rule that returns the url path.
The function version is passed two params: $injector and $location services, and must return a url string.

Why do I need to call a dynamic route ":_id" and not whatever I want?

Here's a rather standard way to set a route in Iron Router:
Router.route('/posts/:_id', {
name: 'postPage',
data: function() { return Posts.findOne({_id: this.params._id}) }
});
Experimenting around a little, beginner as I am, I tried:
Router.route('/posts/:whatever', {
name: 'postPage',
data: function() { return Posts.findOne({_id: this.params.whatever}) }
});
This works well, up to a point. True, whatever will scoop up whatever is after /posts/ as its value, and the data context will indeed be the same as before... but linking to specific posts now won't work!
So,
{{title}}
simply won't work doing it "my" way (linking to nothing at all).
I can't fully wrap my head around this, and I'm too much of a novice to grasp the source code for Iron Router, so my hope is that someone here can explain it in a manner that even a beginner like me can comprehend.
Preferably like something like this:
First {{pathFor 'postPage'}} looks inside the routes to find the one named postPage.
It sees that this route corresponds to /posts/ followed by something else.
Looking inside the data context it finds that only one post is returned, namely the one with the same _id as whatever comes after /posts/.
It understands that it should link to this post, cleverly setting the url to /posts/_id.
This is wrong, most likely, and it doesn't explain why it would work when whatever is turned into _id. But it would help me immensely to see it parsed in a similar fashion.
Edit: Cleaned up my question so it is easier to grasp.
There's a simple set of circumstances that together lead to confusion:
The Posts.findOne issue is explained by the fact that the first argument can be either a selector or a document _id. So it's not really a shortcut but rather a documented feature.
As you found, putting :something in the iron:router URL causes that value to be reported as this.params.something inside the route function. This also registers something as an parameter to that route, which brings us to how pathFor works.
The pathFor helper takes two inputs: first the name of the route (in this case 'postPage') and second an object of parameters, which can come either from the second argument as in {{pathFor 'postPage' params}} or from the data context like so: {{#with params}}{{pathFor 'postPage'}}{{/with}}.
Now, here's why passing in a document from the database works if you call the parameter _id but not if you call it whatever: the post object that you retrieved from the database _has an _id field, but it doesn't have a whatever field. So when you pass it into pathFor, it only passes along the correct _id if the parameter to the route also happens to be called _id.
Let me know if that makes sense, I agree that this is somewhat confusing and that this "shortcut" hides what exactly pathFor and params actually do.

AngularJS $routeParam vs $location.search(a,b) difference?

Setting a URL parameter via $routeParams, or setting it using $location.search() as a setter seem to achieve the same thing, other than how the parameter appears in the URL, and where in the app it is set.
From app.js config...
$routeProvider
.when('/myRoute/:myParam', {});
vs.
From a controller...
$scope.setLocationParam = function (name, param) {
$location.search(name, param);
};
I have a simple ajax app where I'm going step-by-step through a few pages and I want to maintain state in the URL so that each subsequent route is calling an api based on URL params set from the previous route.
When would one want choose one method over the other?
I'm leaning towards a search param via $location because it's more descriptive but I thought I'd ask you fine people!s

Can ui-router handle multiple parameters in AngularJS?

I have an app that is currently built to have a static base URL with a parameter at the end. I would like to instead have the base URL default to one vaule, but have the ability to built routes based on several options. So for now its set up as:
.state('ball', {
parent: 'ballLayout',
url: '/ball/{urlName}',
views: {
'cube.head': {
templateUrl: 'partials/views/ball.head.html',
controller: 'BallCtrl'
}
}
});
The static ball value is what I'd like to change. Basically I'd like to have an optional list of incoming URLs that would work, but when nothing is present it defaults to ball. So for instance:
ball/title-of-page
bat/title-of-page
basket/title-of-page
beast/title-of-page
These would all work, and when constructing the URL it would default to ball/
Is something like this possible? How would one go about implementation.
I dont think what I'm asking here can actually be done without having issues with other parameters. Instead Im asking a new question about Regex from incoming links to reroute to my angular URL.

Categories

Resources