Passing Data to Angular Routed Components: 5 Best Ways

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

How to Pass Data to Angular Routed Components: A Complete TypeScript Guide

\n\n

Every developer who starts working with Angular eventually faces the question: "How do I pass data from one component to another through the router?". On Stack Overflow, this question has gathered thousands of views — and for good reason. Unlike regular parent-child components, where using @Input() and @Output() is sufficient, routing in Angular adds its own complexities.

\n\n

In this article, we will cover 5 proven ways to pass data in Angular routed components. You will learn when to use which method and get ready-to-use examples in TypeScript. Let's go!

\n\n

Why Can't You Just Pass Data via @Input?

\n\n

Many beginners try to do this:

\n\n
// ❌ This doesn't work\n<router-outlet [someData]="data"></router-outlet>
\n\n

The Angular Router creates components dynamically. router-outlet is a directive, not a template element. Therefore, passing data directly through attributes is impossible. But there are workarounds — and they are even more convenient!

\n\n

Method 1: Using Router State (Simplest)

\n\n

The most intuitive way is to pass data through the state object during navigation. This method has been available since Angular 7+ and works out of the box.

\n\n

How It Works

\n\n

You pass an object with data when calling router.navigate() or via routerLink.

\n\n
// Component A — sender\nimport { Component } from '@angular/core';\nimport { Router } from '@angular/router';\n\n@Component({\n  selector: 'app-user-list',\n  template: `\n    <button (click)="goToDetails()">Open User</button>\n  `\n})\nexport class UserListComponent {\n  constructor(private router: Router) {}\n\n  goToDetails() {\n    this.router.navigate(['/user', 42], {\n      state: { name: 'Ivan Petrov', role: 'admin' }\n    });\n  }\n}
\n\n
// Component B — receiver\nimport { Component, OnInit } from '@angular/core';\nimport { Router } from '@angular/router';\n\n@Component({\n  selector: 'app-user-details',\n  template: `\n    <div *ngIf="userData">\n      <h2>{{ userData.name }}</h2>\n      <p>Role: {{ userData.role }}</p>\n    </div>\n  `\n})\nexport class UserDetailsComponent implements OnInit {\n  userData: any;\n\n  constructor(private router: Router) {\n    // Get data from navigation history\n    this.userData = this.router.getCurrentNavigation()?.extras?.state;\n  }\n\n  ngOnInit() {\n    // Alternative method — via history.state\n    if (!this.userData) {\n      this.userData = history.state;\n    }\n  }\n}
\n\n

Pros and Cons

\n
    \n
  • ✅ Simple to implement
  • \n
  • ✅ Data is not visible in the URL
  • \n
  • ✅ Works with any data types (objects, arrays)
  • \n
  • ❌ Data is lost on page refresh
  • \n
  • ❌ Does not work when navigating directly via URL
  • \n
\n\n

When to use: for passing temporary data that is not critical on reload (e.g., flash messages, filters).

\n\n

Method 2: Route Resolver (For Preloading Data)

\n\n

If you need to load data before the component is displayed, use an Angular Resolver. This is a service that resolves data before the route is activated.

\n\n

Creating a Resolver

\n\n
// user.resolver.ts\nimport { Injectable } from '@angular/core';\nimport { Resolve, ActivatedRouteSnapshot } from '@angular/router';\nimport { Observable, of } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class UserResolver implements Resolve<any> {\n  resolve(route: ActivatedRouteSnapshot): Observable<any> {\n    const userId = route.paramMap.get('id');\n    // Im                

Blogs

Book Recommendations