Language as param in Vue Router - javascript

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('/');

Related

Creating a home page dynamically in NextJs

I'm trying to create all my pages using NextJs with the slugs/uri I get when fetching the data, however when trying to create the home page it says.
Error: The provided path `/` does not match the page: `/[slug]`.
[slug].tsx is located in the page folder. I removed the index.js since I would like to have the home page the same page layout as other pages.
Currently getting the static paths like this:
export async function getStaticPaths() {
const allPages = await getAllPostsWithSlug();
return {
paths: allPages.edges.map(({ node }) => `${node.uri}`) || [],
fallback: true,
};
}
The error I got makes sense, but I couldn't really find a solution to create my home page in the same page template.
As per the documentation, you can use an optional catch-all route.
Name your page file [[...slug]].js, and then use something like the this for the paths prop in getStaticPaths:
paths: [
{ params: { slug: [] } },
{ params: { slug: ['foo'] } },
{ params: { slug: ['bar'] } },
]
FWIW - if you want to share components from the main template (i.e. header, nav, footer etc), I recommend using a custom _app.js page. If your homepage really is identical to your other pages, it might be worth re-visiting the design!
Good luck!
Since [...slug] is not the same as [slug] as it grabs sub-paths as well, you can achieve a closer match using just [slug].js and adding a rewrite to your next.config.js like so:
async rewrites() {
return [
{
source: '/',
destination: '/homepage',
},
]
},
Then you handle the homepage slug as your homepage, just like any other CMS page or post.
(/homepage can be anything you want, e.g. /index)

How to reuse route on query params change, but not on path params change in Angular?

Say I have 2 routes '/users' and /users/:id. First one renders UserListComponent and second UserViewComponent.
I want to re-render component when navigating from /users/1 to /users/2. And of course if I navigate from /users to /users/1 and vice versa.
But I DON'T want to re-render component if I navigate from /users/1?tab=contacts to /users/1?tab=accounts.
Is there a way to configure router like this for entire application?
--
Update:
I'm importing RouterModule in AppRoutingModule like this:
RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })
I'm using Angular 12
The default behavior of the Angular router is to preserve the current component when the URL matches the current route.
This behavior can be changed by using the onSameUrlNavigation option:
Define what the router should do if it receives a navigation request
to the current URL. Default is ignore, which causes the router ignores
the navigation. This can disable features such as a "refresh" button.
Use this option to configure the behavior when navigating to the
current URL. Default is 'ignore'.
Unfortunately, this option is not fine-grained enough to allow reload for path params and ignore for query params.
So you have to subscribe both to the query params and the path params changes with something like this:
constructor(route: ActivatedRoute) { }
ngOnInit() {
this.renderLogic();
this.route.params.subscribe(() => this.renderLogic());
this.route.queryParams.subscribe(() => this.renderLogic());
}
renderLogic() {
// ...
}
As far as I know, #Guerric P is correct, you can't completely re-render the component selectively like this, at least not without some trickery like subscribing to each event and then possibly blocking it for one scenario and not the other. Feel free to try something like that, but below is an alternative if you make use of resolvers to fetch your data.
What you can do is use runGuardsAndResolvers in your route configuration like so:
const routes = [{
path: 'team/:id',
component: Team,
children: [{
path: 'user/:name',
component: User
}],
runGuardsAndResolvers: 'pathParamsChange',
resolvers: {...},
canActivate: [...]
}]
This will, as the name suggests, run your guard resolver logic again. If you fetch data using resolvers and pass it into your components, you can update what your component displays only when the path or params change.

Vue Routing and Regex Patterns

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.

vue.js / vue-router - create instance of single file component with props to route to

My goal is to further reduce code and the most obvious one in my project is to abstract lists. Currently I have a vue single file component called List which includes an async data loader. I've also created a bunch of 'derived' single file components using this List component as root tag element, passing props as needed to load the correct data.
Now, since I've split up my components into separate files using this plugin it is common to have a folder structure which looks like this:
\components\
\components\List\
\components\List\List.vue
\components\List\List.vue.js
\components\List\List.scoped.vue.css
\components\List\List.vue.html
As you can see, 4 files per component. Imagine having 10 different list components all using List as their base. That is 10 folders with a total of 40 files. And for what? Pretty much the same code, 2-3 values that change (the properties), the rest stays the same.
I've been trying to adjust List so that I can create an instance of it and pass the properties as constructor values. Why? Instead of having 1 folder with 4 files per list, I could just have the base List and the create the components like so:
let FooList = new List('foo', true, {}, (x) => {});
let BarList = new List('bar', false, {}, (y) => {});
I want to use these objects in the vue-router like so:
const router = new Router({
...
routes: [
{
path: "some/foo,
component: FooList,
},{
path: "any/bar,
component: BarList,
},
]
});
Anything I tried failed.
What have I tried so far?
export default { ... } exports a default single file component. I figured if this is a component, I might as well just override some values in it.
How did I try to do this?
I tried using Object.assign({ ... }, List) in the hope of creating a List object which has the properties defined like I want them to be.
I also tried using the vue built in "extends" option of single files components to extend List, but this doesn't save code at all since I still need to define a template/render method for the component .. which results in those 4 files again. I tried to use Vue.component(..) and Vue.extend(..), alone and in combination but couldn't succeed.
Anything I tried resulted either in a max stack exceeded exception (recursion gone wrong), vue errors were thrown stating that something doesn't fit or just not displaying anything at all.
Is there a way of doing this?
You could define a prop on the List component to specify the type of list and modify the behavior.
let routes = [
{
path: '/home',
name: 'home',
component: List,
props: { config: { type: 'Listing', display: 'Tile' } }
},
]

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});

Categories