React router ignores URL after // for multiple optional parameters - react-router-v4

I want to match this url https://localhost:8050/search/Contact//* to the path given below.
<Route path="/search/:type?/:subType?/:query?" component={TestComponent}?>
As subtype is optional parameter so I am passing blank instead.
But the "query" parameter is ignored all together.
I get match as follows in props
match {
params: {type: "Contact", subType: undefined, query: undefined}
path: "/search/:type?/:subType?/:query?"
url: "/search/Contact"
}
I want * to be mapped with query in match params

If you are not using :subType then remove it or use 2 different routes.
<Route exact path="/search/:type?/:query?" component={TestComponent}?>
<Route path="/search/:type?/:subType?/:query?" component={TestComponent}?>

Related

how to make params that automatically scrolls to a section

I want to have a route like this.
http://localhost:8080/help/category/newuser#1
Therefore, I write this in my template
<router-link
v-bind:to="{
name: 'help',
params: { id: selectedCategory+'#'+eachQuestion.id },
}"
>
But this doesn't work and resulting in
http://localhost:8080/help/category/newuser%231
So the # turns into %23. How to solve this? Thanks!
You can navigate to a route with params by passing the param names as an object:
params: { category: selectedCategory }
If you are also passing a hash value, you're able to declare the hash property as well:
hash: eachQuestion.id

vuejs - How to concatenate text to named route

How can I concatenate named route to router-link tag? My code:
<router-link
:to="'//https://t.me/share/url?url='+{name: Profile, params: {id: user.user_id}}+'&text=Hi I am ' + user.first_name + ' ' + user.last_name + ':'">Click Here</router-link>
The problem is this part:
{name: Profile, params: {id: user.user_id}}
it returns [Object object]. How can I fix it to return correct value of this object which is http://example.com/profile/1 as an example?
There is no need to use router-link for external links, since it's click should not be processed with vue-router.
I'd suggest to create a computed property (or method) that will return a full url with all data included. Which also will remove certain logic from a template, as a good practice.
Template link will look as follow:
<a :href="telegramLink">Open Telegram</a>
And computed property to generate the link:
computed: {
telegramLink () {
const user = this.user
// Get route information by provided parameters
const route = this.$router.resolve({
name: 'Profile',
params: {
id: user.user_id
}
})
// Create full address url
const url = `${window.location.origin}${route.href}`
const text = `Hi I am ${user.first_name} ${user.last_name}:`
return `https://t.me/share/url?url=${url}&text=${text}`
}
}

vuejs this.$route issue with address bar

When I remove a parameter, It does not take effect in address bar.
I tried following line to remove parameter from URL.
delete this.$route.query[parameter_name];
See below url, Notice following things.
In console query object is empty but address bar having all parameters.
I tried following lines to remove applicants and branches parameters from URL. It only effected in console as you can see query object is empty but URL is still there.
delete this.$route.query['applicants'];
delete this.$route.query['branches'];
But still address bar is having all removed params.
donate#/?applicants=Female&branches=2207962
Using delete will delete the property but will not update the address bar.
You need to specify a redirect programmatically. See Programmatic Navigation.
You can use
this.$router.push('donate')
Or
this.$router.replace('donate')
to replace the current history entry (see comment from #thanksd)
This will work with $router.push or $router.replace to clear the query string.
Clear the query string inside a component lifecycle hook.
mounted() {
this.$router.replace({ query: { '': null } });
}
Clear the query string on redirect.
$router.push({ path: 'url-path', query: { '': null } })
$router.replace({ path: 'url-path', query: { '': null } })
Remove old query string values and replace with new values.
$router.push({path: 'url-path', query: {'': null, lastname: 'Ever', firstname: 'Greatest'}})
$router.replace({ path: 'url-path', query: { '': null token: 'coolToken' })

React Router 4 / path-to-regexp multiple optional segments

In React router 3 I could have path like this:
/root(/id/:id)(/di/:di)
That would match
/root
/root/id/1
/root/di/2
/root/id/1/di/2
Perfect.
I can't figure out how to do it in React Router 4. All examples are doing only one thing.
Using Express Route tester I can come up with a route like
/root/id/:id?/di/:di?
But that would match only
/root/id/1/di/2
Is there a solution for this?
In react router v4 you can enclose your regex inside (). So this regex should work and match all the paths you gave : /root(/id/|/di/):id*(/id/|/di/)?:di*. In the Express router Tester tool that you gave the link to, the keys wont show up with this regex but it does work, I tested on localhost and keys works just fine.
Note that I didn't use ? after first capturing group, i.e., (/id/|/di/) because if I did then it would become optional and then path like /root/12 would be matched too.
Here's how I did it in the end, it's a litte bit ridiculous but it works:
<Route
path="/root/:firstKey?/:firstId?/:secondKey?/:secondId?"
render={({ match: { params: { firstKey, secondKey, firstId, secondId } } }) => {
const params = { [firstKey]: firstId, [secondKey]: secondId }
return (<Whatever {...params} />)
}}
/>

Dynamic parameter in href option in Aurelia Routing config.map

This seems like a really simple issue, but it's driving me crazy...
Does anyone know how I can specify a dynamic :id parameter in the href routing configuration option?
The following unfortunately doesn't work:
config.map([
// ... default parameterless routing here
{
route:[':id/request'],
moduleId:'processes/bdd/request/request',
name:'Request', title:'Request', href:`#/bdd/request/${id}/request`, settings:{type:'Request', icon:''}, nav:true,
},
{
route:[':id/requestAuth'],
moduleId:'processes/bdd/request/requestauthorization',
name:'RequestAuthorization', title:'Request Authorization', href:`#/bdd/request/${id}/requestAuth`, settings:{type:'Request', icon:''}, nav:true,
},
// ... some additional mappings here
]);
The href property is static. If you want to generate a route for a link using this route, you could use the route-href custom attribute like this:
route-href="route: request; params.bind: { id: someProp }"
Note that I changed the route name to be camelCase (all lowercase since it is one word here) to match the route naming convention.
I had a similar use case and I was able to get this to work by adding a pipeline step to the router that alters the config on the fly.
My use case may be a little different in that I only want the item to appear in the nav bar when the route is active -- say I have routes /abc, /def/:id, and /ghi -- when the active route is ABC or GHI, only those items will appear in the nav bar, but when the active route is DEF, it should appear in the nav bar, and clicking it should lead to the same DEF ID you're currently looking at. So my route configuration includes a setting that indicates the route should only appear in the nav bar when it's the active route.
Here are the interesting parts of my actual configureRouter function:
configureRouter(config, router) {
config.addPreActivateStep(Preactivate); // explained below
config.map([
// some routes
{ route: 'patients/:patientId', name: 'patient-master',
moduleId: 'patients-and-cases/patient-master/patient-master',
title: 'Patient', nav: true, settings: { renderOnlyWhenActive: true },
href: '#' // it doesn't matter what this is
},
// more routes
]);
}
And here is the Preactivate class that sets the href on preactivate:
class Preactivate {
run(routingContext, next) {
routingContext.config.href = routingContext.fragment;
return next();
}
}
If, unlike me, you want this to display in a nav bar all the time, this will still work -- the href will simply remain set to the last thing it was set to when the route was active. In that case you'd probably want to initialize it to some default value that makes sense.