Angular routing keep child parameters - javascript

I have the following route configuration:
const routes: Routes = [
{
path: '',
component: HomeComponent,
canActivate: [AuthGuard],
children: [
{
component: DashboardComponent,
path: ''
},
{
component: UnitComponent,
path: 'unit/:serialnumber',
children: [
{ path: '', redirectTo: 'realtime', pathMatch: 'full'},
{
path: 'manager',
component: UnitManagerComponent,
canActivate: [SysAdminGuard]
},
{ path: 'realtime', component: UnitRealtimeComponent },
{ path: 'history', component: UnitHistoryComponent },
{ path: 'consumption', component: UnitConsumptionComponent },
{ path: 'consumption/:range', component: UnitConsumptionComponent },
{ path: 'edit', component: UnitEditComponent }
]
}
]
}
...
image that i am in current route state
http://127.0.0.1:4200/#/unit/000000003/consumption/monthly
and i want to navigate to another unit with a different serialnumber:
http://127.0.0.1:4200/#/unit/000000001/consumption/monthly
if i make
this.router.navigate(['/unit','000000001'])
i will go to http://127.0.0.1:4200/#/unit/000000001/realtime
is there any way to change a specific parameter in the route and keep the childs route ?

Related

Routes outside navigation guards vue

I have an application in vue with vue router that works correctly, also in the router I use navigation guards to protect my routes, the problem is that now I want to have routes or components that work outside the navigation guards, for example a page of password recovery that the user receives a link and can access it directly, my problem is that i want to access to a recovery password direct from a external link it always redirects me to the login, I share my code:
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: Home,
meta: {
user_type: 1
}
},
{
path: '/check-balance',
name: 'check-balance',
component: CheckBalanceComponent,
meta: {
user_type: 1
}
},
{
path: '/check-payment',
name: 'check-payment',
component: CheckPaymentsComponent,
meta: {
user_type: 1
}
},
{
path: '/payment-disabled',
name: 'payment-disabled',
component: DisabledMakePaymentComponent,
meta: {
user_type: 1
}
},
{
path: '/handle-payment',
name: 'handle-payment',
component: HandlePaymentsComponent,
meta: {
user_type: 1
}
},
{
path: '/handle-report',
name: 'handle-report',
component: HandleReportsComponent,
meta: {
user_type: 1
}
},
{
path: '/user-profile',
name: 'user-profile',
component: UserProfileComponent,
meta: {
user_type: 1
}
},
{
path: '/recover-password',
name: 'recover-password',
component: RecoverPasswordComponent,
meta: {
free: 1 //this outside navigation guards
}
},
{
path: '/recover-link',
name: 'recover-link',
component: RecoverLinkComponent,
meta: {
free: 1
}
},
{
path: '/login',
name: 'login',
component: LoginComponent,
meta: {
free: 1
}
},
{
path: '/help',
name: 'help',
component: HelpComponent,
meta: {
user_type: 1
}
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to, from, next) => {
if(to.matched.some(record => record.meta.free)){
next()
}
else if(store.state.user && store.state.user.user_type == 1){
next()
}
else {
next({
name: 'login'
})
}
})
export default router

Vue-Router: Refresing(F5) current page

When I press refresh(F5) button then my router directs me to the main page. How do I stay on the same page when the page is refreshed?
that's route, mode is 'history'
const routes = [
{ path: '*', redirect: '/' },
{
path: '/', component: template_Default, redirect: '/Login',
children: [
{ path: 'Login', component: login_, name: 'Login' },
{ path: 'SignUp', component: signUp_, name: 'SignUp' }
]
},
{
path: '/Main', component: template_Home, name: 'Main', redirect: '/Main/Overview',
children: [
{ path: 'Overview', component: overview_, name: 'Overview' },
{ path: 'Customer', component: customer_, name: 'Customer' },
{ path: 'Task', component: task_, name: 'Task' },
{ path: 'Order', component: order_, name: 'Order' },
{ path: 'Product', component: product_, name: 'Product' },
{ path: 'Setting', component: setting_, name: 'Setting' }
]
},
{
path: '/ForgotPassword', component: forgotPassword_, name: 'ForgotPassword',
// redirect: '/ForgotPassword/GetEmail',
// children: [
// { path: 'GetEmail', component: forgotPasswordGetEmail, name: 'GetEmail' },
// { path: 'ReSend', component: forgotPasswordReSend, name: 'ReSend' }
// ]
}
]
And my controller,
router.beforeEach((to, from, next) => {
// redirect to login page if not logged in and trying to access a restricted page
const publicPages = ['/Login','/SignUp','/ForgotPassword'];
const authRequired = !publicPages.includes(to.path);
const loggedIn = store.getters.isLoggedIn;
if (authRequired && !loggedIn) {
return next('/Login');
}else next();
if(loggedIn){
AuthController.IsOnline();
}
})
thanks in advance..
The issue is that you have { path: '*', redirect: '/' } as the first item in your routes array. According to the documentation:
When using asterisk routes, make sure to correctly order your routes so that asterisk ones are at the end.
This is because Vue Router searches through your list of routes in order and returns the first matching route. An asterisk is going to match any and all routes so, when you refresh the page, it returns the first route and redirects you to '/'.
Same problem here, but my route have no { path: '*', redirect: '/' }
Here is my code.
export const routes = [
{
path:'/login',
component: login,
name: 'home'
},
{
path:'/',
component: mainapp,
name: 'mainapp',
meta: {
requiresAuth: true
},
children: [
{
path:'/dash',
component: dashboard,
name: 'dashboard'
},
{
path:'/dept',
component: dept,
name: 'department'
},
{
path: '/deptDetail',
component: deptDetail,
name: 'detail'
},
{
path:'/hrd',
component: HRD
},
{
path:'/notify',
component: notify
},
{
path:'/device',
component: device
},
{
path:'/setup',
component: setup,
name: 'setup'
},
{
path:'/scanArea',
component: area,
},
{
path:'/env',
component: environment,
},
{
path:'/record', /* debug page */
component: record,
},
{
path:'/redis', /* debug page */
component: redis,
},
{
path:'/permit',
component: permit,
},
{
path:'/app',
component: app,
}
]
},
]

Angular 6: outlet name showing on url how to remove it?

router-outlet name showing on url.
How to remove this I found the same question on StackOverflow here is the link but there no answer was given. so I posted this again. In my project
URL showing like : http://localhost:4200/dashboard/(dashboardSection:profile)
but I want to make it like:
http://localhost:4200/dashboard/profile
http://localhost:4200/dashboard/list
I have provided all the code for routing.
app.module.ts
const appRoutes: Routes = [
{ path: 'home', component: HomeComponent},
{ path: 'sign-up', component: SignUpComponent, canActivate: [PreventLoggedInAccess] },
{ path: 'file', component: FileUploadComponent, canActivate: [AuthGuard] },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard],
children:[
{
path: "list",
component: ListingListComponent,
outlet: 'dashboardSection'
},
{
path: "profile",
component: ProfileEditComponent,
outlet: 'dashboardSection'
}
]
},
{ path: '',
redirectTo: 'home',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];
on Import section #NgModule({});
RouterModule.forRoot(
appRoutes,
{ enableTracing: false } // <-- debugging purposes only
),
dashboard.component.html
<li [routerLink]="['/dashboard',{ outlets: { dashboardSection: ['list'] }}]" routerLinkActive="active">List</li>
<li [routerLink]="['/dashboard',{ outlets: { dashboardSection: ['profile'] } }]" routerLinkActive="active">profile</li>

Angular Unit testing : Error: Cannot match any routes. URL Segment: 'home/advisor'

Am working on unit testing under my angular 4.0.0 app , some method in my real component is calling manual routing via :
method(){
....
this.navigateTo('/home/advisor');
....
}
with navigateTo is a custom routing method calling this :
public navigateTo(url: string) {
this.oldUrl = this.router.url;
this.router.navigate([url], { skipLocationChange: true });
}
i have this routing file :
import ... // Components and dependencies
const homeRoutes: Routes = [
{
path: 'home', component: HomeComponent,
children: [
{
path: 'registration',
component: RegistrationComponent,
children: [
{
path: 'synthese',
component: SyntheseComponent
},
{
path: 'queue',
component: QueueComponent,
children: [
{
path: 'queue-modal',
component: QueueModalComponent
},
{
path: 'confirm',
component: ConfirmComponent
}
]
}
]
},
{
path: 'toolbox',
component: ToolboxComponent
},
{
path: 'appointment',
component: AppointmentRegistrationComponent
},
{
path: 'appointment-validation',
component: AppointmentValidationComponent
},
{
path: 'datepicker',
component: DatePickerComponent
},
{
path: 'validation/:defaultNumber',
component: ValidationComponent,
children: [
{
path: 'synthese',
component: SyntheseComponent
}
]
},
{
path: 'modalField',
component: ModalFieldComponent
},
{
path: 'search',
component: SearchComponent
},
{
path: 'advanced-search',
component: AdvancedSearchComponent
},
{
path: 'tools',
component: ToolsComponent
},
{
path: 'advisor',
component: AdvisorComponent
},
{
path: 'pilote',
component: PilotComponent
},
{
path: 'blank',
component: BlankComponent
},
{
path: 'view-360/:id',
component: View360Component,
children: [
{
path: 'client',
component: ClientComponent
},
{
path: 'tools',
component: ToolsAdvisorComponent
},
{
path: 'valid-close',
component: ValidCloseComponent
},
{
path: 'application',
component: ApplicationView360Component
}
],
canActivate: [AuthGuardAdviser]
},
{
path: 'view-360',
component: View360Component,
children: [
{
path: 'client',
component: ClientComponent
}
],
canActivate: [AuthGuardAdviser]
},
{
path: 'contract',
component: ContractComponent
},
{
path: 'queue-again',
component: QueueAgainComponent
},
{
path: 'stock',
component: StockComponent,
children: [
{
path: 'mobile',
component: MobileComponent
},
{
path: 'stock-level',
component: StockLevelComponent
}
]
},
{
path: 'usefull-number',
component: UsefullNumberComponent
},
{
path: 'admin',
loadChildren: 'app/home/admin/admin.module#AdminModule',
// component: AdminComponent,
canActivate: [AuthGuardAdmin]
},
{
path: 'rb',
loadChildren: 'app/home/rb/rb.module#RbModule',
// component: RbComponent
// canActivate: [AuthGuardAdmin]
},
{
path: 'tools-advisor',
component: ToolsAdvisorComponent
},
{
path: 'catalog/:haveClient',
component: CatalogComponent
},
{
path: 'application',
component: ApplicationComponent
},
]
},
];
#NgModule({
imports: [
CommonModule,
RouterModule.forChild(homeRoutes)
],
exports: [
RouterModule
],
declarations: []
})
export class HomeRoutingModule { }
Strangely , even my application goes fonctionnally well ,but the test throws this error :
Failed: Uncaught (in promise): Error: Cannot match any routes. URL
Segment: 'home/advisor' Error: Cannot match any routes. URL Segment:
'home/advisor'
it seems like i have some missing configuration .
Any ideas ??
You need RouterTestingModule.withRoutes like so:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes(
[{path: 'yourpath', component: BlankComponent}]
)
],
declarations: [
BlankComponent,
YourComponentBeingTested
]
})
.compileComponents()
}))
Following my comment :
When you want to unit test your router, you have to use the testing module, not the actual one.
Start with
import { RouterTestingModule } from '#angular/router/testing';
Then, in your Testbed
imports: [RouterTestingModule]
Now you should be able to unit test your component
EDIT
To make a spy on your routing, what you have to do is
spyOn(component.router, 'navigate').and.returnValue(true);
And you expect will look like
expect(component.router.navigate).toHaveBeenCalledWith('/home/advisor');
I run into same issue. The solution of accepted answer doesn't work for me, because I accidentally added the HttpClientModule instead of HttpClientTestingModule to my Spec files. To avoid the "Can not match any routes" issue be sure you add RouterTestingModule and HttpClientTestingModule everywhere it is needed.
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
HttpClientTestingModule,
],
declarations: [
AppComponent
],
}).compileComponents();
}));
In my console, I am getting this error while running my unit test case because of SubRoute. I am able to fix this issue by implementing the following way in my unit test case.
class RouterStub {
url = '';
navigate(commands: any[], extras?: any) { }
}
beforeEach(async(() => {
TestBed.configureTestingModule({
providers:[{ provide: Router, useClass: RouterStub }]
}).compileComponents();
}));

One Outlet for multiple route Angular 2

I'm working with AngularJS 2 routes. I have one layout with fixed header and dynamic sidebar and dynamic content. I have created following routes:
const appRoutes: Routes = [
{
path: '', component: DashboardComponent, children: [
{ path: '', component: HeaderComponent, outlet: 'header' },
{ path: '', component: SidebarComponent, outlet: 'sidebar' },
{ path: '', component: ContentComponent, outlet: 'content' },
{ path: 'profile', component: ProfileComponent, outlet: 'content' }
],
},
{ path: 'login', component: LoginComponent },
];
When I visit to my home page i.e. http://localhost/ it works fine. Currently what I need is for profile page only my content outlet should change keeping same header and sidebar content as my home page.
Main thing is when I visit to /profile page it should show the same header and sidebar content and only content which is inside content outlet should change and should show my profile content data.
I have created following routerLink
[routerLink]="['/profile']"
Try moving /profile as a children of ContentComponent.
const appRoutes: Routes = [{
path: '', component: DashboardComponent, children: [
{ path: '', component: HeaderComponent, outlet: 'header' },
{ path: '', component: SidebarComponent, outlet: 'sidebar' },
{ path: '', component: ContentComponent, outlet: 'content'
children: [
{ path: 'profile', component: ProfileComponent }
]
},
]},
{ path: 'login', component: LoginComponent },
];
EDIT 1
Maybe you can try to create a LayoutComponent in which you can have the named outlets and a generic outlet for your template.
something like:
const appRoutes: Routes = [
{ path: '', component: LayoutComponent,
children: [
{ path: '', component: HeaderComponent, outlet: 'header' },
{ path: '', component: SidebarComponent, outlet: 'sidebar' },
{ path: '', component: ContentComponent,
children: [
{ path: '', component: DashboardComponent }
{ path: 'profile', component: ProfileComponent }
]
},
]
},
{ path: 'login', component: LoginComponent }
];
// LayoutComponent template
<router-outlet name="header"></router-outlet>
<router-outlet name="sidebar"></router-outlet>
<router-outlet></router-outlet>

Categories

Resources