Vue Routing and Regex Patterns - javascript

I'm using Vue and recently introduced a route with a parameter.
const routes = [
{
path: "/:lang(^$|^es$|^pt$|^cn$)",
name: "Home",
component: Page,
},
{
path: "/privacy",
name: "Privacy",
component: Privacy,
},
{
path: "*",
name: "NotFound",
component: NotFound,
}
];
I want the route to trigger when one of the following conditions is met.
lang is empty
lang is either es or pt or cn but no combinations of those.
Everything else should go to the NotFound route
The regex I'm using above works on the javascript engine of https://regexplanet.com
I tried all sorts and variations to make it work in Vue but to no avail so far.

I believe the path you need is:
path: "/:lang(|es|pt|cn)",
There's a routing tester here that uses the same library as Vue:
https://forbeslindesay.github.io/express-route-tester/
Make sure you're testing against path-to-regexp 0.1.7.
The problem is that the whole path gets converted to a RegExp, not just the bits in the brackets. So your ^ are never going to match anything. Try putting your original path into the testing tool to see how it compiles. The generated RegExp already contains its own ^ and $ but they are relative to the whole path, not just the parameter you're trying to match.

Related

Language as param in Vue Router

I would like to have a language param in my path. For example if there is en before the path, print en.
If I enter http://localhost:8080/en it will give me en but if I enter http://localhost:8080/en/aaaa it will return me undefined
how can I get en anyway?
const routes = [
{
path: "/:lang?",
children: [
{
path: home,
component: home
}
]
}
]
router.beforeEach((to, _, next) => {
console.log(to.params.lang);
}
Under the assumption that you are planning on adding different language support for your app, I would recommend instead using i18n because it will abstract away things like appending params for different languages.
To your specific question on why you are getting undefined, that could simply be because there is no view page or route for the /aaa route. So Vue is just confused on where you want to go.
You can use pure javascript to get the current url and get the parameters through a split.
let myListParams = window.location.href.split('/');

Array in route parameter cause "Expected to not repeat" warning

When I try to create a router-link with an array as parameter, the link works but I get the following warning :
missing param for named route "start-run": Expected "files" to not repeat, but received ["aaa"]
router.js
...
{
path: '/start-run/:config?/:files?',
name: 'start-run',
component: StartRun,
props: true
},
...
file.vue
...
<router-link :to="{name: 'start-run', params: { config: 'test', files: ['aaa'] }}">...</router-link>
...
I didn't find documentation to fix this warning.
I believe the error message comes from path-to-regexp version 1.7.0, which is used by Vue Router:
https://github.com/pillarjs/path-to-regexp/blob/v1.7.0/index.js#L185
The problem is that an array is treated as multiple values but the parameter in your path does not support multiple values.
It is unclear what you are trying to achieve by passing an array to files. The route path you've defined uses a ? suffix for :files?, which makes it optional but doesn't allow for an array. Perhaps you meant :files* or :files+ instead? Or maybe you just want to pass the first item in the array?

I'm using this.$router.push to navigate programmatically, however, I'm being sent to wrong URL and I'm not sure why

I'm using nested routes so that might be causing the issue, however, I'm not sure how to fix it. I have the following route and children routes:
{
path: '/summoner/:summonerName',
component: Summoner,
children: [
{ path: '', component: Matchlist },
{ path: '/match/:matchId', component: SpecificMatch, name: 'specificMatch' }
]
},
When I'm on path /summoner/:summonerName I want to see the default Summoner parent component and the Matchlist component and when I'm on path /summoner/:summonerName/match/:matchId I want to see the default Summoner parent and the specificMatch child component. This works fine, however, when I try to use:
this.$router.push({ name: 'specificMatch', params: { summonerName: this.summoner, matchId: matchId, summonerInfo: this.summonerInfo, match: match}})
I get sent to /match/:matchId path instead of /summoner/:summonerName/match/:matchId which breaks the component because the components needs to get the username from the path. I assumed this.$router.push would send me to the correct path, alas no. Any tips how to fix this?
It's a matter of absolute and relative paths.
Your route with the name 'specificMatch' has the specified absolute path '/match/:matchId' so this is where you are navigated to. If you wish to append your path to the path of your parent route you will have to make your path relative, which means to leave out the initial slash (/) - e.i. path: 'match/:matchId'.

How to keep query string parameters in URL when accessing a route of an Angular 2 app?

I have an Angular 2 test app running the latest alpha (37). There are just three routes, that look like this:
#RouteConfig([
{ path: '/', component: Home, as: 'home' },
{ path: '/errors', component: Errors, as: 'errors' },
{ path: '/about', component: About, as: 'about' }
])
I can access the routes, and when I place query string params in the URL I can read them just fine. However, a few instants after I read the parameters, I noticed that the route loads fine and the URL refreshes, removing the query string parameters.
In other words, accessing this route:
http://localhost:5555/errors?test=abc
Loads the /errors route, but right after the application loads the URL turns into:
http://localhost:5555/errors
That would be confusing to a user. I would like to keep the query string parameters in the URL.
I know, it's in alpha, but is this a bug or I forgot to set something up on the router? How can I keep whatever query string parameters in the URL?
Thanks!
This is fixed in Alpha 41. The query string is now persisted.
Updating for Angular 2:
To preserve query parameters present in the current url, add
// import NavigationExtras
import { NavigationExtras } from '#angular/router';
// Set our navigation extras object
// that contains our global query params
let navigationExtras: NavigationExtras = {
preserveQueryParams: true
};
// Navigate to the login page with extras
this.router.navigate(['/someLink'], navigationExtras);
For more info, check here:
Try this
this.router.navigate(['target'], {preserveQueryParams: true});

How to enforce typing of route params?

I have set up the following paths:
this.resource('areaManagement', { path: '/management/areas' }, function() {
this.route('assign', { path: '/assign' });
this.route('new', { path: '/new' });
this.route('subdivide', { path: '/:id' });
});
If you wanted to create a new area, you would go to /management/areas/new, but in testing, I accidentally went to /management/areas/create and noticed no error was thrown. Then I realized, this path is matching the subdivide dynamic segment.
If this is how dynamic segments work, then technically, /management/areas/anythingyouwant will be a valid/recognized path. I could always implement a model() hook and redirect/error if :id isn't an integer, but is there a way to make the router enforce this?
I think an "easy" workaround would be to add a new nesting level by adding a
path: '/id'
to have a URL like
/management/areas/id/1
Not necessarily idealbut would help you here.

Categories