Como transferir dados em componentes roteados do Angular: guia completo em TypeScript
\n\nTodo desenvolvedor que começa a trabalhar com Angular, mais cedo ou mais tarde, enfrenta a questão: «Como transferir dados de um componente para outro através do roteador?». No Stack Overflow, essa pergunta acumulou milhares de visualizações — e não é por acaso. Ao contrário dos componentes parent-child comuns, onde basta usar @Input() e @Output(), o roteamento no Angular adiciona suas próprias complexidades.
Neste artigo, vamos analisar 5 maneiras comprovadas de transferir dados em Angular routed components. Você aprenderá quando usar cada método e obterá exemplos prontos em TypeScript. Vamos lá!
\n\nPor que não podemos simplesmente transferir dados via @Input?
\n\nMuitos iniciantes tentam fazer assim:
\n\n// ❌ Não funciona\n<router-outlet [someData]="data"></router-outlet>\n\nO Angular Router cria componentes dinamicamente. router-outlet é uma diretiva, não um elemento de template. Portanto, a transferência de dados diretamente através de atributos é impossível. Mas existem soluções alternativas — e elas são ainda mais convenientes!
Método 1: Usando Router State (o mais simples)
\n\nA maneira mais intuitiva é transferir dados através do objeto state durante a navegação. Este método apareceu no Angular 7+ e funciona «de fábrica».
Como funciona
\n\nVocê passa um objeto com dados ao chamar router.navigate() ou através de routerLink.
// Componente A — remetente\nimport { Component } from '@angular/core';\nimport { Router } from '@angular/router';\n\n@Component({\n selector: 'app-user-list',\n template: `\n <button (click)="goToDetails()">Abrir usuário</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// Componente B — receptor\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>Função: {{ userData.role }}</p>\n </div>\n `\n})\nexport class UserDetailsComponent implements OnInit {\n userData: any;\n\n constructor(private router: Router) {\n // Obtém os dados do histórico de navegação\n this.userData = this.router.getCurrentNavigation()?.extras?.state;\n }\n\n ngOnInit() {\n // Maneira alternativa — via history.state\n if (!this.userData) {\n this.userData = history.state;\n }\n }\n}\n\nPrós e contras
\n- \n
- ✅ Simplicidade de implementação \n
- ✅ Dados não visíveis na URL \n
- ✅ Funciona com qualquer tipo de dado (objetos, arrays) \n
- ❌ Dados são perdidos ao atualizar a página \n
- ❌ Não funciona ao acessar diretamente pela URL \n
Quando usar: para transferir dados temporários que não são críticos ao recarregar (por exemplo, mensagens flash, filtros).
\n\nMétodo 2: Route Resolver (para pré-carregamento de dados)
\n\nSe você precisa carregar dados antes que o componente seja exibido, use o Angular Resolver. É um serviço que resolve os dados antes da ativação da rota.
\n\nCriando um 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