Advanced Routing LAURENT DUVEAU JUNE 7TH, 2018
© LDEX, 2015Angular Vancouver Meetup, June 2018 Laurent Duveau @LaurentDuveau I am based in Montreal, Qc Founder of the Angular Academy 2-day Angular Classroom Training 111 classes in 2 years! Montreal, Quebec, Toronto, Ottawa , Vancouver, Calgary, Winnipeg, London, Copenhagen, Helsinki…
© LDEX, 2015Angular Vancouver Meetup, June 2018 ADVANCED ROUTING Agenda Lazy Loading Preloading Modules Router events Diagnostic with traces Auxiliary routes Routes Transitions (Animations) Guards Resolve
© LDEX, 2015Angular Vancouver Meetup, June 2018 Requirement I assume you already know the basics of Angular Routing… … do you ? 4
Lazy Loading 5
© LDEX, 2015Angular Vancouver Meetup, June 2018 LAZY LOADING Lazy Loading ?
© LDEX, 2015Angular Vancouver Meetup, June 2018 LAZY LOADING Lazy load the Products Module! const routes: Routes = [ {path: '', redirectTo:'/home', pathMatch:'full'}, {path: 'products', loadChildren:'./products/products.module#ProductsModule'}, {path: 'home', component: HomeComponent}, {path: 'contact', component: ContactComponent}, ]; app.routing.ts
© LDEX, 2015Angular Vancouver Meetup, June 2018 LAZY LOADING Make its routes relative to ‘products/’ const routes: Routes = [ { path: 'products', component: ProductListComponent }, { path: 'products/:id', component: ProductDetailComponent } ]; products.routing.ts const routes: Routes = [ { path: '', component: ProductListComponent }, { path: ':id', component: ProductDetailComponent } ]; products.routing.ts
© LDEX, 2015Angular Vancouver Meetup, June 2018 LAZY LOADING Do not import lazy loaded modules! @NgModule({ imports:[BrowserModule, HttpModule, ProductsModule] }) export class AppModule { } app.module.ts @NgModule({ imports:[BrowserModule, HttpModule] }) export class AppModule { } app.module.ts
© LDEX, 2015Angular Vancouver Meetup, June 2018 DEMONSTRATION 10
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Preloading Modules! Preload lazy-loadable modules in the background while the user is interacting with your application 11
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Preloading Modules! 12
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Preloading Modules! 13
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Preloading Modules! 14
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Preloading Modules! 15
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Preloading Modules! One built-in preloading strategy: PreloadAllModules Create your Custom Preloading Strategy! Class that implements PreloadingStrategy 16 @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })], exports: [RouterModule], }) export class AppRoutingModule { }
© LDEX, 2015Angular Vancouver Meetup, June 2018 DEMONSTRATION 17
Router Events
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Router Events Event Description NavigationStart Navigation starts RoutesRecognized Router parses the URL and the routes are recognized RouteConfigLoadStart Before the Router lazy loads a route configuration RouteConfigLoadEnd After a route has been lazy loaded NavigationEnd Navigation ends successfully NavigationCancel Navigation is canceled. This is due to a Route Guard returning false during navigation NavigationError Navigation fails due to an unexpected error
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Router Events 20 @Component({ selector: 'my-app', template: `<router-outlet></router-outlet>` }) export class AppComponent { constructor(private router: Router) {} ngOnInit() { this.router.events .subscribe((event) => { if (event instanceof NavigationEnd) { console.log('NavigationEnd:', event); } }); } }
© LDEX, 2015Angular Vancouver Meetup, June 2018 DEMONSTRATION 21
Diagnostic with traces 22
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Activate traces 23 @NgModule({ imports: [RouterModule.forRoot(routes, { enableTracing: environment.production ? false : true } )] }) export class AppModule { } app.module.ts
© LDEX, 2015Angular Vancouver Meetup, June 2018 DEMONSTRATION 24
Auxiliary Routes
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Auxiliary Routes Navigation happens in a <router-outlet></router-outlet> We can have more than one! So we can navigate to several routes at the same time
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Auxiliary Routes Create a named router-outlet Add a route to target this outlet Link to navigate to the outlet 27 <router-outlet></router-outlet> <router-outlet name="popup"></router-outlet> {path:'contact', component:ContactComponent, outlet:'popup'} <a [routerLink]="[{outlets: {popup:['contact']}}]">Contact</a>
© LDEX, 2015Angular Vancouver Meetup, June 2018 DEMONSTRATION 28
Routes Transitions (Animations) 29
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Animations Define animations files 30 import { trigger, animate, transition, style } from '@angular/animations'; export const fadeInAnimation = // trigger name for attaching this animation to an element using the [@triggerName] syntax trigger('fadeInAnimation', [ // route 'enter' transition transition(':enter', [ // css styles at start of transition style({ opacity: 0 }), // animation and styles at end of transition animate('.5s', style({ opacity: 1 })) ]), ]); fade-in.animation.ts
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Animations Import BrowserAnimationsModule Use component decorator 31 @Component({ selector: 'app-product-list’, animations: [fadeInAnimation], host: { '[@fadeInAnimation]': ''} }) export class MyComponent { animation to use attached to host to run animation when component is activated
© LDEX, 2015Angular Vancouver Meetup, June 2018 DEMONSTRATION 32
Guards
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Routes Guards CanActivate CanDeactivate NavigationNavigation Component Decides if a route can be activated - User logged-in ? Decides if a route can be deactivated - Form saved ?
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Routes Guards 35 export class LoginRouteGuard implements CanActivate { constructor( private loginService: LoginService, private router: Router) {} canActivate() { if(!this.loginService.isLoggedIn()) { this.router.navigateByUrl("/login"); return false; } return true; } } login-route-guard.service.ts { path: 'admin', component: AdminComponent, canActivate: [LoginRouteGuard] }, app-routing.module.ts
© LDEX, 2015Angular Vancouver Meetup, June 2018 DEMONSTRATION 36
Route Resolver 37
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING Route Resolver Pre-fetching component data before navigating Avoid a blank component while waiting for the data to be returned from the server Pre-fetch data from the server so it's ready the moment the route is activated! Create a service and implement the Resolve interface
© LDEX, 2015Angular Vancouver Meetup, June 2018 DEMONSTRATION 39
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING 40 https://vsavkin.com
© LDEX, 2015Angular Vancouver Meetup, June 2018 ROUTING 41 https://leanpub.com/router
© LDEX, 2015Angular Vancouver Meetup, June 2018 Amazing Angular Classroom Training! 42
© LDEX, 2015Angular Vancouver Meetup, June 2018 Thank you!

Angular Advanced Routing

  • 1.
  • 2.
    © LDEX, 2015AngularVancouver Meetup, June 2018 Laurent Duveau @LaurentDuveau I am based in Montreal, Qc Founder of the Angular Academy 2-day Angular Classroom Training 111 classes in 2 years! Montreal, Quebec, Toronto, Ottawa , Vancouver, Calgary, Winnipeg, London, Copenhagen, Helsinki…
  • 3.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ADVANCED ROUTING Agenda Lazy Loading Preloading Modules Router events Diagnostic with traces Auxiliary routes Routes Transitions (Animations) Guards Resolve
  • 4.
    © LDEX, 2015AngularVancouver Meetup, June 2018 Requirement I assume you already know the basics of Angular Routing… … do you ? 4
  • 5.
  • 6.
    © LDEX, 2015AngularVancouver Meetup, June 2018 LAZY LOADING Lazy Loading ?
  • 7.
    © LDEX, 2015AngularVancouver Meetup, June 2018 LAZY LOADING Lazy load the Products Module! const routes: Routes = [ {path: '', redirectTo:'/home', pathMatch:'full'}, {path: 'products', loadChildren:'./products/products.module#ProductsModule'}, {path: 'home', component: HomeComponent}, {path: 'contact', component: ContactComponent}, ]; app.routing.ts
  • 8.
    © LDEX, 2015AngularVancouver Meetup, June 2018 LAZY LOADING Make its routes relative to ‘products/’ const routes: Routes = [ { path: 'products', component: ProductListComponent }, { path: 'products/:id', component: ProductDetailComponent } ]; products.routing.ts const routes: Routes = [ { path: '', component: ProductListComponent }, { path: ':id', component: ProductDetailComponent } ]; products.routing.ts
  • 9.
    © LDEX, 2015AngularVancouver Meetup, June 2018 LAZY LOADING Do not import lazy loaded modules! @NgModule({ imports:[BrowserModule, HttpModule, ProductsModule] }) export class AppModule { } app.module.ts @NgModule({ imports:[BrowserModule, HttpModule] }) export class AppModule { } app.module.ts
  • 10.
    © LDEX, 2015AngularVancouver Meetup, June 2018 DEMONSTRATION 10
  • 11.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Preloading Modules! Preload lazy-loadable modules in the background while the user is interacting with your application 11
  • 12.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Preloading Modules! 12
  • 13.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Preloading Modules! 13
  • 14.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Preloading Modules! 14
  • 15.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Preloading Modules! 15
  • 16.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Preloading Modules! One built-in preloading strategy: PreloadAllModules Create your Custom Preloading Strategy! Class that implements PreloadingStrategy 16 @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })], exports: [RouterModule], }) export class AppRoutingModule { }
  • 17.
    © LDEX, 2015AngularVancouver Meetup, June 2018 DEMONSTRATION 17
  • 18.
  • 19.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Router Events Event Description NavigationStart Navigation starts RoutesRecognized Router parses the URL and the routes are recognized RouteConfigLoadStart Before the Router lazy loads a route configuration RouteConfigLoadEnd After a route has been lazy loaded NavigationEnd Navigation ends successfully NavigationCancel Navigation is canceled. This is due to a Route Guard returning false during navigation NavigationError Navigation fails due to an unexpected error
  • 20.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Router Events 20 @Component({ selector: 'my-app', template: `<router-outlet></router-outlet>` }) export class AppComponent { constructor(private router: Router) {} ngOnInit() { this.router.events .subscribe((event) => { if (event instanceof NavigationEnd) { console.log('NavigationEnd:', event); } }); } }
  • 21.
    © LDEX, 2015AngularVancouver Meetup, June 2018 DEMONSTRATION 21
  • 22.
  • 23.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Activate traces 23 @NgModule({ imports: [RouterModule.forRoot(routes, { enableTracing: environment.production ? false : true } )] }) export class AppModule { } app.module.ts
  • 24.
    © LDEX, 2015AngularVancouver Meetup, June 2018 DEMONSTRATION 24
  • 25.
  • 26.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Auxiliary Routes Navigation happens in a <router-outlet></router-outlet> We can have more than one! So we can navigate to several routes at the same time
  • 27.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Auxiliary Routes Create a named router-outlet Add a route to target this outlet Link to navigate to the outlet 27 <router-outlet></router-outlet> <router-outlet name="popup"></router-outlet> {path:'contact', component:ContactComponent, outlet:'popup'} <a [routerLink]="[{outlets: {popup:['contact']}}]">Contact</a>
  • 28.
    © LDEX, 2015AngularVancouver Meetup, June 2018 DEMONSTRATION 28
  • 29.
  • 30.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Animations Define animations files 30 import { trigger, animate, transition, style } from '@angular/animations'; export const fadeInAnimation = // trigger name for attaching this animation to an element using the [@triggerName] syntax trigger('fadeInAnimation', [ // route 'enter' transition transition(':enter', [ // css styles at start of transition style({ opacity: 0 }), // animation and styles at end of transition animate('.5s', style({ opacity: 1 })) ]), ]); fade-in.animation.ts
  • 31.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Animations Import BrowserAnimationsModule Use component decorator 31 @Component({ selector: 'app-product-list’, animations: [fadeInAnimation], host: { '[@fadeInAnimation]': ''} }) export class MyComponent { animation to use attached to host to run animation when component is activated
  • 32.
    © LDEX, 2015AngularVancouver Meetup, June 2018 DEMONSTRATION 32
  • 33.
  • 34.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Routes Guards CanActivate CanDeactivate NavigationNavigation Component Decides if a route can be activated - User logged-in ? Decides if a route can be deactivated - Form saved ?
  • 35.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Routes Guards 35 export class LoginRouteGuard implements CanActivate { constructor( private loginService: LoginService, private router: Router) {} canActivate() { if(!this.loginService.isLoggedIn()) { this.router.navigateByUrl("/login"); return false; } return true; } } login-route-guard.service.ts { path: 'admin', component: AdminComponent, canActivate: [LoginRouteGuard] }, app-routing.module.ts
  • 36.
    © LDEX, 2015AngularVancouver Meetup, June 2018 DEMONSTRATION 36
  • 37.
  • 38.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING Route Resolver Pre-fetching component data before navigating Avoid a blank component while waiting for the data to be returned from the server Pre-fetch data from the server so it's ready the moment the route is activated! Create a service and implement the Resolve interface
  • 39.
    © LDEX, 2015AngularVancouver Meetup, June 2018 DEMONSTRATION 39
  • 40.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING 40 https://vsavkin.com
  • 41.
    © LDEX, 2015AngularVancouver Meetup, June 2018 ROUTING 41 https://leanpub.com/router
  • 42.
    © LDEX, 2015AngularVancouver Meetup, June 2018 Amazing Angular Classroom Training! 42
  • 43.
    © LDEX, 2015AngularVancouver Meetup, June 2018 Thank you!