Angular 2 Router: route everything behind a certain route - javascript

We're creating a new version of an app, and need to keep legacy routes working. Legacy urls come into our app under a specific route, let's call it legacy.
So, if a route is /legacy/route1, I am going to handle it with a Resolver to tell where it's actually supposed to go within our app (the old url routing scheme is very convoluted and needs quite a bit of logic). However, if it comes in under /legacy/route1/subroute3/somethingelse, I'd like to handle it with the same resolver.
How do I catch all of these routes within a single or a couple of lines in my RouterModule? I've tried all of the below:
{ path: 'legacy', component: Legacy, resolve: [LegacyRouteResolver] },
{ path: 'legacy/', component: Legacy, resolve: [LegacyRouteResolver] },
{ path: 'legacy/*', component: Legacy, resolve: [LegacyRouteResolver] },
{ path: 'legacy/**', component: Legacy, resolve: [LegacyRouteResolver] }
but none of them will give me any routes that come in with multiple slashes, and there are many other circumstances under which they fail (the octothorp seems to throw them off, too)

you can use below,
{
path: 'legacy',
children: [
{path : '**' , component: Legacy}
]
}
this will match all the routes after legacy
Hope this helps!!

Related

Redirect on startup by the given browser URL

I created a new Vue app with a base path. Due to the fact the app is embedded into another Vue app, this app doesn't render the router-view on startup. If you want to know more about how or why this app is embedded into another app, please have a look here:
mount Vue apps into container of main Vue app
and my own answer to this problem:
https://stackoverflow.com/a/58265830/9945420
When starting my application, it renders everything except the router-view. I want to redirect on startup by the given browser URL. This is my router config:
import Vue from 'vue';
import Router from 'vue-router';
import One from './views/One.vue';
import Two from './views/Two.vue';
Vue.use(Router);
const router = new Router({
base: '/my-embedded-app/',
mode: 'history',
routes: [
{
path: '/',
component: One,
},
{
path: '/two',
component: Two,
},
],
});
router.replace(router.currentRoute.fullPath);
export default router;
I want the app to render the component Two when calling .../my-embedded-app/two. Unfortunately, router.replace always redirects to / (so the browser URL is .../my-embedded-app/). I debugged the router, and saw that the path is /, but I would expect it to be /two.
Important note:
I don't want to redirect the user to /two whenever the url is /. I just want to render the view Two when the url is /two. Currently it doesn't.
What might be wrong? Maybe I don't even need that redirect, and can solve the problem a more elegant way.
updated: jsfiddle
What wound up happening is that route.currentRoute.fullPath was executed before router was ready.
That's the normal behavior, it is the way single page application works. The "pound" - like # - sign means that the links will not move the application to another page.
so you can change the router mode to
mode:"hash"
Try beforeEnter. Have a look at the below code:
const router = new Router({
base: "/my-embedded-app/",
mode: "history",
routes: [
{
path: "/",
component: One,
beforeEnter: (to, from, next) => {
// Your are free to add whatever logic here.
// On first visit
next("/two");
}
},
{
path: "/two",
component: Two
}
]
});
Read more about Navigation guards here
Could you provide a github repo or some to test the actual?
Otherwise my first idea is to use children routes with an "empty" view as base, here an example about what I tried. (working in my case)
router.js
export default new Router({
mode: 'history',
base: '/my-embedded-app/',
routes: [
{
path: '/',
name: 'base',
component: Base,
children: [
{
path: '',
name: 'one',
component: One
},
{
path: 'two',
name: 'two',
component: Two
}
]
}
]
})
Base.vue
<template>
<router-view/>
</template>
One.vue
<template>
<div>One</div>
</template>
Two.vue
<template>
<div>Two</div>
</template>

Angular Routes: Problem defining a NotFoundComponent with multiple routings files

I am creating a NotFoundComponent so that every non-existing url, a friendly page will apear to the user.
My Angular 6 project has 5 features(CRUDL):
CompanyComponent,
EmployeeComponent,
BranchComponent,
BenefitsComponent,
MainComponent
Each component have it own .module and .routing, for example the company.routing.ts defines the route like this:
export const routes: Routes = [
{
path: "branch",
component: EmptyComponent,
}
...
#NgModule({
imports: [
RouterModule.forChild(routes),
...
it also defines its childrens, like path: "branch/:id".
So, i have no problem with the way i built the routing.
The problem I am facing now is the way I can define a path to the NotFoundComponent.
Because I don't have a single file where I define my routes, if I put the definition of the /404 page on the on the bottom of routers definition in the main.routing.ts, every other route defined on the features(like the company.routing.ts) will be redirected to the /404, since angular uses the first match strategy.
Things i tried so far:
on the main.routing.ts:
export const routes: Routes = [
{
path: "main",
component: MainComponent,
},
{
path: "404",
resolve: {
routeTitle: TitleResolver,
},
component: NotFoundComponent,
},
{
path: "",
pathMatch: "full",
redirectTo: "/main",
},
{
path: "**",
redirectTo: "/404",
}
if I put this way, when I try accessing the route /company (defined in the company.routing.ts) it will be redirected to the /404.
I also tried defining it on any a routing of one of my features, like on the company.routing.ts
{
path: "**",
redirectTo: "/404",
}
Than, a funny thing happened, if I define this piece of code on the benefits.routing.ts, i can access /benefits but /branch, /employee and the rest of the routes will be redirected to /404.
if I define it on branch, I can access /benefits, /branch but /employee and the rest of the routes will be redirected to /404.
I could just place this code on the last feature loaded and it would work but I would like to know if I can solve this with another approach, can't I define a route that I want to be the last one loaded?
thanks in advance.

How to capture more of the path with dynamic route matching?

A link is fetched from the database, e.g. /app/profile.
A single component (master/index.vue) should render any path following the app's address (http://example.com/).
I have the following router configuration:
{
path: '/',
component: () => import('#/components/Layout.vue'),
children: [
{
path: ':id',
component: () => import('#/components/pages/master/index.vue')
}
]
}
… but this is not working as expected. It only accepts one param after example.com. How do I make it work dynamically so that it accepts multiple params, e.g. /app/profile?
you can use an asterisk to match anything, for example:
path: '*',
if you know the base path will be fixed, you can narrow the match to e.g. /*, /app*.
see the vue-router docs on dynamic matching, under the catch all section.

Angular 6: How to use multiple loadChildren with same route?

I have something like:
const routes: Routes = [
{
path: ':path', component: SiteRoot, children: [
{ path: '', loadChildren: '../modules/maple/template.module#TemplateModule' }
]
}
];
I wish to use this :path url to match multiple module dynamically. each module have there own internal Route.
Is there any way I can achieve this?
I tried ViewContainerRef with ResolveComponentFactory but it does not work with module only component. Event with NgModuleFactoryLoader, Routes cannot be applied.
EDIT, to make everything clear:
What I am trying to achieve is to have different module display on same route path. For example user can see user dashboard at "home" path, and admin can see admin dashboard at "home" path as well.
This feature is defined by business logic, so, I cannot change admin dashboard to another url
I think you are trying to create your routing module incorrectly. Anyway, you should write why you need this. I'll try to answer. Every module should have it's own path, so routing module should be strict and static. If you trying it for security, use guards and hide item from menu component.
If you need URLs like this: "/username1/profile", "/username2/profile" you can simply use code like yours, or use lazy loading. create routing file for parent module:
{ path: ':username', loadChildren: '../users/user.module#UserModule' }
Than create routing file for child module:
{ path: '', loadChildren: 'UserComponent', children: [
{ path: '', redirectTo: 'profile' },
{ path: 'profile', component: ProfileComponent}
]
}
Updated By your case:
by your case you can change your HTML file. For example in app.component.html if your code is:
<div>
<router-outlet></router-outlet>
</div>
You can change it with:
<div *ngIf="isLoggedIn | async">
<admin-panel></admin-panel>
</div>
<div *ngIf="(!isLoggedIn | async)">
<router-outlet></router-outlet>
</div>

Angular feature routing module - Child component not loaded

I have a feature module that I load in the AppModule, the AppRoutingModule looks like
const appRoutes: Routes = [
...
{
path: 'move-request/:id',
loadChildren: 'app/modules/move_requests/move_requests.module#MoveRequestModule'
},
...
];
And the configuration of routing for the feature module looks like
const moveRequestRoutes: Routes = [
{
path: '',
component: MoveRequestFormComponent,
data: {title: 'Move Request'}
},
{
path: 'move-request-success',
component: RequestSuccessComponent,
data: {title: 'Move request success'}
},
];
I would like to navigate to MoveRequestFormComponent as the default component when move-request/:id is routed to, this works fine, but when I call
this.router.navigate(['/move-request-success', {}]);
In MoveRequestFormComponent after some response from the server, I get
zone.js:665 Unhandled Promise rejection: Cannot match any routes. URL Segment: 'move-request-success' ; Zone: <root> ;
This configuration was working before I switched to Angular 6, Is it because of the change in the AppModule, where I have excluded this feature module as an import?
Any assistance on what I am missing would be much appreciated. As I have also tried with having a third component which will be the default component and uses the router-outlet to render the children and have a children property on this route to have as children
{
path: '',
component: MoveRequestFormComponent,
data: {title: 'Move Request'}
},
{
path: 'move-request-success',
component: RequestSuccessComponent,
data: {title: 'Move request success'}
},
But that also did not work, it stayed on the MoveRequestFormComponent, when 'move-request-success' was navigated to.Or maybe I should change the approach?
You don't have to import the feature module in AppModule as it is lazily-loaded. When you navigate to move-request/:id/move-request-success, the path matches the default route with path:'', and then it will look for and children of that route. You should add pathMatch:'full' to the first route, which is the default in this case. Since the mentioned route matches the first route and is unable to find and match any children, it is showing the error.
this.router.navigate(['/move-request-success', {}]);. If you add a / to a route this means you use absolute path from root. Have you tried without / ?
EDIT:
I think I see your problem. You navigate to a module with multiple components, which means after lazy loading the router configuration from the loaded module is used. This means
move-request/:id
Is the root of your module and every subroute needs to include the modules root in the url:
Your route should be move-request/:id/move-request-success
Urls in lazy loaded modules are:
module root (in your case move-request/:id) + configured route of the specific component (in your case move-request-success)

Categories

Resources