Nuxt: Use multiple params for dynamic routing - vue.js

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?

Related

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.

Is there a named routes and default params equivalent for Razor Pages page routes?

I have a JobPosts/Index page with multiple GET parameter bindings to allow filtering: let's take CityId and IsRemote for example. I don't want these to be passed as query string parameters, instead I want to use friendly routes for them. So I have defined these:
options.Conventions.AddPageRoute("/JobPosts/Index", "cities/{cityId}/jobs");
options.Conventions.AddPageRoute("/JobPosts/Index", "remote-jobs");
options.Conventions.AddPageRoute("/JobPosts/Index", "jobs");
The routes work just fine when I type them in the browser and the CityId one is bound properly, but two things are missing.
First, there is no way to specify a default value for my IsRemote param, which I want to set to true ONLY when using the remote-jobs URL.
And second, when trying to generate a URL like this:
<a asp-area="" asp-page="/JobPosts/Index" asp-route-cityId="#Model.CityId"></a>
I get the following URL:
https://localhost:44391/jobs?cityId=2265885
When what I actually expect is:
https://localhost:44391/cities/2265885/jobs
So it looks like the tag helper or the part responsible for constructing the URL doesn't look at all at the different routes to try and get a best match based on the list of parameters. Actually, it will always use the last page route defined for that page.
Nor do I have the option anywhere to specify a route name for the page route and then use asp-route to explicitly say which route I want.
Any ideas how to achieve that? Or if it's something that's on the roadmap for Razor Pages?
EDIT: Hardcoding the href is not an option. I want this to go through the proper routing services as there are other things to be done as well, like generating culture-specific URL for non-english users (eg. {cultureId}/cities/{cityId}/jobs - this is done through route conventions. Hardcoding the href would obviously bypass that.
There is a easy way to set IsRemote default value.
public bool IsRemote { get; set; } = true;
This tag asp-page will link to Page /JobPosts/Index.csthml directly,
https://localhost:44391/JobPosts?cityId=2265885
= https://localhost:44391/JobPosts/Index?cityId=2265885
If you are looking forward the URL https://localhost:44391/jobs?cityId=2265885
you could try this a tag to request.
Go to JobPosts
———————————————————————————————
Using a middleware to handle /remote-jobs
app.Run(next => async context =>
{
if (context.Request.Path == "/remote-jobs")
{
return View with default IsRemote
}
});

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.