Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 Admin navigation/routes separate from Client side navigation/routes

Tags:

angular

I know Angular 2 likes to use a single navigation to switch between pages. My issue is that the admin navigation is completely different than client facing navigation.

My goal is to have an admin and all of its routes run separate from the client side and all of its routes.

For example: If you go the root page, or the /video page, you deal with client side routers and navigation. If you go to /admin or /admin/client, you deal with only the admin side routers and navigation.

Is this even possible with Angular 2/4?

If so, can you point me to some advantageous reading?

Thanks.

like image 690
William Gates III Avatar asked Jun 18 '17 20:06

William Gates III


People also ask

Can we have multiple routes in Angular?

Angular Router supports multiple outlets in the same application. A component has one associated primary route and can have auxiliary routes. Auxiliary routes enable developers to navigate multiple routes at the same time.

Can we use 2 router-outlet in Angular?

You can have multiple router-outlet in same template by configuring your router and providing name to your router-outlet, you can achieve this as follows. Advantage of below approach is thats you can avoid dirty looking URL with it. eg: /home(aux:login) etc.

Can we define multiple router outlets in a component view?

Yes! We can use multiple router-outlets in same template by configuring our routers and simply add the router-outlet name. You can see in the example.

What is the purpose of wildcard route in Angular?

Setting up wildcard routeslink To add this functionality to your application, you set up a wildcard route. The Angular router selects this route any time the requested URL doesn't match any router paths. To set up a wildcard route, add the following code to your routes definition.


2 Answers

Here is a possible solution using basic routing and a guard to guard specific routes for admin priviledges only.

In your routing config you will define the two main routes /user & /admin. You can then define child routes for those two main routes where they will extend off the parent route (example /admin/dashboard or /user/account)

You can then regulate who has access to those routes based on a user role or whatever you decide. If you're storing user details in local storage, you can also store the users roles.

Below is an untested example. I have comments inside the code blocks with a little explanation. I've also supplied a few links to write ups on routing and guards. Hopefully this helps a bit.

Routing Config

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 Guard

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's 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 Child Routes https://angular-2-training-book.rangle.io/handout/routing/child_routes.html

Angular CanActivateChild https://angular.io/api/router/CanActivateChild

More on routing https://blog.thoughtram.io/angular/2016/06/14/routing-in-angular-2-revisited.html

like image 104
Jason White Avatar answered Sep 18 '22 12:09

Jason White


You can have routing set up in multiple places, including specialised routing modules.

You can then import multiple routing modules in another root module for example.

Please refer to the documentation which gives you loads of examples with all the possible configurations: angular routing module

Edit

From the angular docs, here is how one would set up an angular routing module for certain 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 this is imported in 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 several routing modules and import them in other modules as you wish.

like image 32
v2d Avatar answered Sep 21 '22 12:09

v2d