Vue-router Getting dynamic path from routes in this.$route.matched - vue-router

I’m trying to create a breadcrumb using this.$route.matched
An example path: /projects/:projectId/project-details
So the this.$route.matched array has 3 route objects:
Route 1 path: /projects
Route 2 path: /projects/:projectId
Route 3 path: /projects/:projectId/project-details
When I print to the console the route path, it doesn’t interpolate the dynamic :projectId and instead prints out /projects/:projectId.
Is there any way to get the dynamic :projectId interpolated in the path in a non-hacky way?
Basically I want to set up a router-link where :to="routePath", where routePath is "/projects/33" instead of "/projects/:projectId".

Related

Nuxt: Use multiple params for dynamic routing

I have set up a working dynamic route with 'id' as the dynamic parameter:
<nuxt-link :to="{ name: `blog-id`, params: { id: item.id }}">Link</nuxt-link>
But I'd prefer to use my pages slug as the parameter AND still somehow pass the id. Like only using ./blog/very-awesome-slug.
I know how to simply use the slug instead of the id but, since there will be an API call to http://my-backend/api/pages/${this.$route.params.id}, the id is also needed.
So how would I set up dynamic routing where the slug is used for the route itself but an id is also passed along to call the API?

vue router.push in nuxt using route.name

I use nuxt and have following Problem. My old code looks like this:
this.$router.push({path: "about/me"})
Now I need to make the same call with some params:
this.$router.push({path: "about/me", params: {sendNotification: "1"}})
This obviously doesn't work since vue-router only allowes to use params with name and not path, so it has to look like:
this.$router.push({name: ..., params: {sendNotification: "1"}})
I could do it with query instead of params but I don't want my url to look ugly.
The problem with nuxt is, or at least this is my understanding of nuxt, that it generates the route names using folder structure and in my case also the locale. So the name of this route is actually: "personal-about-me__en".
So my question: Is there a way to get the route.name dynamically, so I could write something like:
this.$router.push({name: getRouteNameByPath("about/me"), params: {sendNotification: "true"}})
The name of the route path is matching the name prop that you can give to the .vue file. So, write is as name: 'AboutMe' key property and use it in the router with { name: 'about-me' }.
Also, vue devtools have a router tab with the name of all the available routes.
This obviously doesn't work since vue-router only allowes to use params with name and not path.
Why do you need to pass params alongside the path? You are supposed to add the params to the path itself, which is why vue-router doesn't allow a separate params object.
So for e.g. assuming your dynamic route is about/me/:sendNotification, you can either provide params with the named route:
this.$router.push({name: ..., params: {sendNotification: "1"}});
which directs you to about/me/1.
OR you can push the entire path including the params
this.$router.push({ path: 'about/me/1' });
Both will produce the exact same result.

vue-router: how to check if current route is a route or one of its subroutes?

I'm wrapping router-link to add some features.
I need to check if current route is a route or a subdolder of a route.
Something like the following
I know it cannot works, because :active need a boolean, but javascript String.match returns an array;: it's to explain my goal
:active="$route.name.match('customer_users*')"
In my router.js I definied that /customer/{customer_id}/users is named customer_users and that /customer/{customer_id}/users/{user_id} is named customer_users_edit.
So i'd like to be able to set ":active" in my wrapper for both these routes.
Use the $route.matched property to see if the current route is your customer_users or any of its children.
For example, using Array.prototype.some()
:active="$route.matched.some(({ name }) => name === 'customer_users')"
See https://v3.router.vuejs.org/api/#route-object-properties
$route.matched
type: Array<RouteRecord>
An Array containing route records for all nested path segments of the current route.

Losing router.params on page refresh

I'm encountering an issue with vue-router.
I got a list of posts in the homepage. When I click on one of them, it redirects to the post page such as :
<router-link :to="{ name: 'article', params: {id: article.id, slug: article.slug } }"></router-link>
Everything is working perfectly, I can retrieve the data of the correct article using this.$route.params.id in a getter.
My issue : When I reload on an article page, this.$route.params.id is undefined, which causes the entire application to crash.
How can I save the router.params despite a page reload ?
What backend are you using? You need to enable history mode on your router, as well as make some additional configuration changes on your backend web server. Please refer to this link for the additional server side configuration changes you will need to make for this to work properly.
Also, please make note of this 404 caveat when using history mode..
Edit: you could try something like this since the ID remains persistent in the URL: Look for the solution from MIKE AXLE
I don't know if anyone else if facing the same issue, but I was having a problem getting route params on refresh. The route parameter I was trying to get was an ID number and I use that ID to fetch data and populate the page. I found (through many console logs) when I refreshed, the number was turning into a string and thats why the page was not working. I sorted it out but casting the ID to number before using it:
Number($route.params.id)
You can also use query instead of params
<router-link :to="{ name: 'article', query: {id: article.id, slug: article.slug } }"></router-link>
and to get value on redirecting page
this.$route.query
I'm not sure what is your route definition, the problem can be that only one of the params presented in the route URL (e.g. /article/:slug).
When you invoke a route (by clicking on router-link or calling router.push), you passing both params directly and they persist in the memory. That's why both are accessible.
But when you reload the page - everything that Vue can do is to parse your URL.
Means only one param parsed because only one param is present.
As a solution you can:
use both params in the route URL (e.g. /article/:id/:slug);
or use one param and call your API to retrieve remaining information (e.g. get id by slug if your route is /article/:slug).
I had the same issue pass the url in router
/article/:id/:slug
you will not loose your params after resfresh because whenrefreshng vue will take only data from url and forget if you passed params
You should route like this:
{
path: '/article/:id/:slug',
name: 'article',
}
In your view when routing do it like this:
this.$router.push({ name: 'article', params: { id: articleID, slug: articleSlug}});
You're welcome! 😉

Vue.js getting params from router-link bind

How can I get the params giving not trough the url but trough a post like params?
<router-link v-bind:to="{
path: '/city/'+city.topicID,
params: { countryCode: countryCode, city: city } }">
Chat
</router-link>
this.$route.params does not seem to work and will on show the topicID.
In the router-link documentation, it mentions that router-link just passes the contents of the "to" to router.push().
In the router.push() documentation, it mentions that if you have both a "path" and "params", the params are ignored. Specifically, it says:
Note: params are ignored if a path is provided, which is not the case for query, as shown in the example above. Instead, you need to provide the name of the route or manually specify the whole path with any parameter
So, you'll need to use a named route if you wish to use params, and then build your path in the named route definition.