← Back to list

Learn Angular — Part 3: Routing, Lazy Loading, Guards, Forms (Template vs Reactive), and State…

· 1. Angular Routing Basics · 2. Lazy Loading in Angular   ∘ Where Should Lazy Loading Be Used? · 3. Route Guards in Angular   ∘ Types   ∘…

Vishwajeet Patel · 2025-07-07 18:36 · 16 claps · 4.6 min read
#angular-routing #lazy-loading #state-management #forms #learn-angular
Open on Medium ↗
Wiki topics: BIZ · Business Strategy 🌐 · Web Development

Learn Angular — Part 3: Routing, Lazy Loading, Guards, Forms (Template vs Reactive), and State Management (NgRx or Signals).

· 1. Angular Routing Basics · 2. Lazy Loading in AngularWhere Should Lazy Loading Be Used? · 3. Route Guards in AngularTypesCanActivateCanActivateChildCanDeactivateResolveCanLoad · 4. Angular Forms: Template vs ReactiveTemplate-Driven FormsReactive Forms · 5. State Management: NgRx vs SignalsOption 1: NgRx (Redux for Angular)Core Concepts:Example Flow:Option 2: Angular Signals (New in Angular 16+) · Core Concepts:Example:In Components: · Conclusion

1. Angular Routing Basics

Routing allows navigation between different components or views without reloading the page.

  • It helps to navigate between different views/components without full page reload.
  • Enables Single Page Application (SPA) behavior.
  • Supports parameterized routes for dynamic data display (e.g., /user/123).
  • Navigation controls using routerLink and programmatic routing via Router.
  • If instead of routerLink we user href then it will lead to the full page reloading.
// app-routing.module.ts
const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: '**', component: NotFoundComponent }, // Wildcard for 404
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}
<!-- app.component.html -->
<router-outlet></router-outlet>
<a routerLink="/about">Go to About</a>

2. Lazy Loading in Angular

Lazy loading is a design pattern that loads feature modules only when they are required, instead of loading everything at once during the initial app launch.Folder Structure

Where Should Lazy Loading Be Used?

Use lazy loading when:

  • You have multiple feature modules (e.g., Admin, Dashboard, User).
  • Certain modules are not needed immediately (e.g., Settings, Reports).
  • You want to optimize loading times in large-scale applications.
  • Sections are role-based or route-based, like /admin, /profile, /orders.
app/
  ├── features/
  │   └── admin/
  │       ├── admin.module.ts
  │       └── admin-routing.module.ts

Routing for Lazy Module

// app-routing.module.ts
const routes: Routes = [
  { path: 'admin', loadChildren: () => import('./features/admin/admin.module').then(m => m.AdminModule) }
];
// admin-routing.module.ts
const routes: Routes = [
  { path: '', component: AdminDashboardComponent }
];
  • State management across modules might require extra handling (e.g., NgRx store sharing).
  • Can cause delays during navigation if module size is large or network is slow.

3. Route Guards in Angular

Route Guards are interfaces provided by Angular that control navigation to and from components based on specific conditions like authentication, unsaved changes, permissions, etc.

They act like middleware for routes.

Types

  • CanActivate: Before entering a route
  • CanDeactivate: Before leaving a route
  • Resolve: Fetch data before loading component
  • CanLoad: Before loading a lazy modul

Example:

CanActivate

Used to check access before navigating to a route.

@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;
  }
}
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }

CanActivateChild

Applied to nested routes.

{ 
  path: 'admin', 
  component: AdminComponent,
  canActivateChild: [AdminGuard],
  children: [
    { path: 'settings', component: SettingsComponent }
  ]
}

CanDeactivate

Prevents navigation if certain conditions are not met (like unsaved form data).

canDeactivate(component: FormComponent): boolean {
  return component.isFormSaved() || confirm('Discard changes?');
}
{ path: 'edit/:id', component: EditComponent, canDeactivate: [ConfirmExitGuard] }

Resolve

Used to fetch data before route activation and inject it into the component.

resolve(): Observable<Data> {
  return this.apiService.getData();
}
{ path: 'profile/:id', component: ProfileComponent, resolve: { user: UserResolver } }

CanLoad

Used to block lazy-loaded modules from being loaded.

canLoad(): boolean {
  return this.authService.hasAdminRole();
}
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule), canLoad: [AdminGuard] }

4. Angular Forms: Template vs Reactive

Angular offers two powerful ways to handle forms:

  1. Template-Driven Forms — Driven by the template (HTML)
  2. Reactive Forms — Driven by the component class (TypeScript)

Template-Driven Forms

Ideal for simple forms; logic resides in the HTML.

  • Forms are simple and static.
  • You want quick setup with minimal code.
  • Ideal for small to medium apps.
<form #userForm="ngForm" (ngSubmit)="submitForm(userForm)">
  <input name="email" ngModel required />
  <button type="submit">Submit</button>
</form>
submitForm(form: NgForm) {
  console.log(form.value);
}

Pros:

  • Less boilerplate
  • Easy to implement

Cons:

  • Harder to unit test
  • Not scalable

Reactive Forms

Code-driven and perfect for complex form logic or validations.

  • Forms are complex, dynamic, or require advanced validations.
  • You need full control over form logic and state.
  • You’re working on large-scale applications.
form: FormGroup;

ngOnInit() {
  this.form = this.fb.group({
    email: ['', [Validators.required, Validators.email]],
    password: ['', Validators.required]
  });
}
<form [formGroup]="form" (ngSubmit)="submitForm()">
  <input formControlName="email" />
  <input type="password" formControlName="password" />
  <button type="submit">Login</button>
</form>

Pros:

  • Better scalability
  • Better control and validation
  • Easy to test

5. State Management: NgRx vs Signals

Angular’s state management is vital for large apps.

In modern Angular applications, managing and sharing state across components and modules becomes critical as your app grows. Angular provides two primary approaches:

  • NgRx — a Redux-style library for complex state management.
  • Signals — Angular’s new reactivity model introduced in Angular 16+.

Option 1: NgRx (Redux for Angular)

NgRx is a state management library that follows the Redux pattern, using a centralized store, actions, reducers, and effects to manage state in a predictable way.

Based on the Redux pattern: Actions → Reducers → State → Effects

Core Concepts:

  • Store: Global state container
  • Actions: Events that describe what happened
  • Reducers: Handle changes to state
  • Effects: Handle side effects (API calls)

Example Flow:

// Action
export const loadUsers = createAction('[User] Load Users');

// Reducer
const userReducer = createReducer(initialState,
  on(loadUsersSuccess, (state, { users }) => ({ ...state, users }))
);
// Effect
loadUsers$ = createEffect(() =>
  this.actions$.pipe(
    ofType(loadUsers),
    switchMap(() => this.userService.getUsers().pipe(
      map(users => loadUsersSuccess({ users }))
    ))
  )
);

Pros:

  • Scalable
  • Strong dev tooling
  • Predictable

Cons:

  • Steep learning curve
  • Boilerplate heavy

Option 2: Angular Signals (New in Angular 16+)

Signals are a new reactivity model built into Angular from v16+, offering fine-grained reactivity similar to useState() in React or reactive primitives in SolidJS.

Signals are reactive primitives that provide fine-grained reactivity.

Core Concepts:

  • signal() – stores reactive values.
  • computed() – derives values from signals.
  • effect() – reacts to changes and performs side effects.

Example:

const counter = signal(0);
const double = computed(() => counter() * 2);

function increment() {
  counter.set(counter() + 1);
}

In Components:

@Component({
  standalone: true,
  template: `Counter: {{ counter() }}`
})
export class CounterComponent {
  counter = signal(0);
}

Pros:

  • Simpler than NgRx
  • No boilerplate
  • Built-in reactivity

Cons:

  • Still evolving
  • Not suitable for very complex app-wide state (yet)

Angular gives you the flexibility to choose between NgRx and Signals depending on your app’s complexity and scalability needs. Use Signals for simplicity and component-level reactivity, and go for NgRx when your app needs structured, centralized, and testable state management.

Conclusion

In this section, we explored Angular’s routing system, discussed the importance of lazy loading, and implemented various types of route guards to secure navigation. We also compared template-driven and reactive forms, highlighting their use cases and differences. Finally, we covered state management using both NgRx and Signals, providing insights into when to choose each approach based on application complexity and scale.


메타데이터
post_id
3246676cae9a
slug
learn-angular-part-3-routing-lazy-loading-guards-forms-template-vs-reactive-and-state-3246676cae9a
url
https://medium.com/@vishwajeet.patel161/learn-angular-part-3-routing-lazy-loading-guards-forms-template-vs-reactive-and-state-3246676cae9a
canonical_url
https://medium.com/@vishwajeet.patel161/learn-angular-part-3-routing-lazy-loading-guards-forms-template-vs-reactive-and-state-3246676cae9a
author_url
https://medium.com/@vishwajeet.patel161
status
ok
fetched_at
2026-06-09 15:37:30