Author: Angus

  • Advanced Angular Routing: Lazy Loading with Route Guards and Resolvers

    Advanced Angular Routing: Lazy Loading with Route Guards and Resolvers

    Angular’s powerful router makes building single page applications seamless, but once your application grows, optimizing routes becomes vital for performance and maintainability. In this article, we’ll delve into intermediate and advanced Angular routing concepts: lazy loading modules, using route guards to protect routes, and leveraging resolvers to fetch data before navigation.

    Why Lazy Loading?

    As Angular applications scale, the bundle size increases, which affects initial load speed. Lazy loading allows us to load feature modules only when needed. This reduces the initial bundle size and speeds up the application startup.

    Setting Up Lazy Loading

    Suppose we have a feature module AdminModule. To lazy load it, our app routing looks like:

    const routes: Routes = [
      { path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }
    ];
    

    When users navigate to /admin, Angular fetches the module on demand.

    Adding Route Guards

    Sensitive routes like /admin may require authentication. We use route guards such as CanActivate to protect them:

    auth.guard.ts

    @Injectable({ providedIn: 'root' })
    export class AuthGuard implements CanActivate {
      constructor(private authService: AuthService, private router: Router) {}
      canActivate(): boolean {
        if (this.authService.isLoggedIn()) {
          return true;
        }
        this.router.navigate(['/login']);
        return false;
      }
    }
    

    Then, in your module’s routing:

    {
      path: '',
      component: AdminComponent,
      canActivate: [AuthGuard]
    }
    

    Data Pre-Fetching with Resolvers

    Sometimes you want to ensure data is available before route activation. This is where resolvers shine.

    admin.resolver.ts

    @Injectable({ providedIn: 'root' })
    export class AdminResolver implements Resolve<AdminData> {
      constructor(private adminService: AdminService) {}
      resolve(route: ActivatedRouteSnapshot): Observable<AdminData> {
        return this.adminService.getAdminData();
      }
    }
    

    Apply it to your routes:

    {
      path: '',
      component: AdminComponent,
      resolve: { adminData: AdminResolver },
      canActivate: [AuthGuard]
    }
    

    Now, AdminComponent receives the resolved data:

    constructor(private route: ActivatedRoute) {
      this.route.data.subscribe(data => {
        this.adminData = data['adminData'];
      });
    }
    

    Key Takeaways

    • Lazy loading optimizes performance by loading modules on demand.
    • Route guards enhance security by controlling access to routes.
    • Resolvers fetch and supply route data before rendering, ensuring a smoother user experience.

    Mastering these Angular routing features leads to more efficient, secure, and user-friendly applications.

  • Beginner’s Guide to Angular Routing

    Beginner’s Guide to Angular Routing

    Routing is a fundamental part of building single-page applications (SPAs) with Angular. It lets you navigate between different views or components, enabling a smooth and dynamic user experience. This guide will walk you through the basics of Angular routing so you can get started adding navigation to your Angular apps!

    What is Routing in Angular?

    Angular routing allows you to display different components or views based on the URL in the browser, without reloading the entire page. Each route maps a URL path to a component.

    Setting Up Routing

    1. Create a New Angular App (if needed):

      ng new my-routing-app
      cd my-routing-app
      
    2. Generate Components:

      ng generate component home
      ng generate component about
      ng generate component contact
      
    3. Configure the Router:
      Open app-routing.module.ts (or create it via ng generate module app-routing --flat --module=app if it doesn’t exist) and define your routes:

      import { NgModule } from '@angular/core';
      import { RouterModule, Routes } from '@angular/router';
      import { HomeComponent } from './home/home.component';
      import { AboutComponent } from './about/about.component';
      import { ContactComponent } from './contact/contact.component';
      
      const routes: Routes = [
        { path: '', component: HomeComponent },
        { path: 'about', component: AboutComponent },
        { path: 'contact', component: ContactComponent },
      ];
      
      @NgModule({
        imports: [RouterModule.forRoot(routes)],
        exports: [RouterModule]
      })
      export class AppRoutingModule {}
      
    4. Enable Router in Your App:
      In app.module.ts, import the AppRoutingModule.

      import { AppRoutingModule } from './app-routing.module';
      // Add AppRoutingModule to the imports array
      
    5. Add Router Outlet:
      In app.component.html (or your root component), add:

      <nav>
        <a routerLink="">Home</a> |
        <a routerLink="/about">About</a> |
        <a routerLink="/contact">Contact</a>
      </nav>
      <router-outlet></router-outlet>
      

      The <router-outlet> directive is where Angular displays the routed component.

    Try It Out!

    Run your app with ng serve, and click the navigation links to see different components render without a full page reload.

    More Routing Features

    • Route Parameters: For dynamic routes (e.g., user profiles) use :id in paths.
    • Wildcard Routes: { path: '**', component: NotFoundComponent } for 404 pages.
    • Route Guards: Control access to certain routes.

    Conclusion

    Angular routing is powerful but easy to get started with. Defining routes, linking to them, and displaying components based on the URL are at the core of building any Angular SPA. Experiment with different features as you get more comfortable!

    Happy coding!