Angular 2 Admin navigation / routes separate from client side navigation / routes
I know Angular 2 likes to use one navigation to switch between pages. My problem is that administering navigation is completely different from client oriented navigation.
My goal is to keep the admin and all of its routes separate from the client and all of its routes.
For example: if you visit a root page or a page / video you are dealing with client side routers and navigation. If you go to / admin or / admin / client, you're only dealing with routers and admin-side navigation.
Is this possible with Angular 2/4?
If so, can you point me to some beneficial reading?
Thank.
source to share
Here is a possible solution using basic routing and guard to protect specific routes for admin privileges only.
In your routing configuration, you define two main routes /user
and /admin
. Then you can define child routes for these two main routes where they will extend from the parent route (example /admin/dashboard
or /user/account
)
You can then regulate who has access to these routes based on the user's role or whatever you decide. If you are saving user data to local storage, you can also save user roles.
Below is an untested example. I have comments inside code blocks with little explanation. I've also provided some links for writing routing and guard posts. Hope this helps a little.
Routing configuration
app.routing.ts
import { NgModule } from '@angular/core';
import { AdminComponent } from './admin.component';
import { AdminDashboardComponent } from './admindashboard.component';
import { UserAccountComponent } from './useraccount.component';
import { UserComponent } from './user.component';
import { RoleGuard } from './role.guard';
const appRoutes: Routes = [
{
path: 'user',
canActivateChild: [RoleGuard], // <-- This guard will run before the router directs you to the route
data: { roles : ['ROLE_USER'] }, // <-- Current Login in user must have role user. You can access this array inside your guard.
children: [
{
path: '', // <-- This should equal /user
component: UserComponent,
pathMatch: 'full'
},
{
path: 'account', // <-- This should equal /user/account
component: UserAccountComponent,
pathMatch: 'full'
}
// <-- The rest of your user routes
]
},
{
path: 'admin',
canActivateChild: [RoleGuard], // <-- This guard will run before the router directs you to the route
data: { roles : ['ROLE_ADMIN'] }, // <-- Current Login in user must have role admin
children: [
{
path: '',
redirectTo: '/admin/dashboard' // <-- Redirects to dashboard route below
},
{
path: 'dashboard',
component: AdminDashboardComponent,
pathMatch: 'full'
}
// <-- The rest of your admin routes
]
}
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes, { useHash: true })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
Role Defense
role.guard.ts
import { Injectable } from '@angular/core';
import { Router, CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
@Injectable()
export class RoleGuard implements CanActivateChild {
constructor(
private router: Router
) {}
canActivateChild(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
const userRoles: string[] = this.authService.getRoles(); // <--------- get the current user roles
const routeRoles: string[] = route.data['roles']; // <------- Will get the roles arry you defined in your router config
/*
Now you can do your logic to determine if the user has the appropriate role.
If they do return true
Else use router to set a redirect route to /user url or whereever you feel like and return false;
*/
}
}
Angular Router http://blog.angular-university.io/angular2-router/
Angular Kids Routes https://angular-2-training-book.rangle.io/handout/routing/child_routes.html
Angular CanActivateChild https://angular.io/api/router/CanActivateChild
More about routing https://blog.thoughtram.io/angular/2016/06/14/routing-in-angular-2-revisited.html
source to share
You can configure routing in multiple locations, including specialized routing modules.
Then you can import multiple routing modules into another root module eg.
Please refer to the documentation which gives you many examples with all possible configurations: angular routing module
Edit
The angular docs describe how the angular routing module can be configured for specific paths.
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
const heroesRoutes: Routes = [
{ path: 'heroes', component: HeroListComponent },
{ path: 'hero/:id', component: HeroDetailComponent }
];
@NgModule({
imports: [
RouterModule.forChild(heroesRoutes)
],
exports: [
RouterModule
]
})
export class HeroRoutingModule { }
And this is how it gets imported into another module:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroService } from './hero.service';
import { HeroRoutingModule } from './heroes-routing.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
HeroRoutingModule
],
declarations: [
HeroListComponent,
HeroDetailComponent
],
providers: [ HeroService ]
})
export class HeroesModule {}
You can create multiple routing modules and import them into other modules as you like.
source to share