Introducción: ¿Por qué Angular grita «Can't resolve all parameters»?
Estás escribiendo tu primer componente de Angular, orgullosamente agregas en el constructor un servicio para trabajar con la API, ejecutas la aplicación — y de inmediato obtienes en la consola un mensaje rojo:
EXCEPTION: Can't resolve all parameters for MyComponent: (?).¿Te suena familiar? Este error es una verdadera piedra de tropiezo para principiantes e incluso para desarrolladores experimentados que migran desde AngularJS. Ocurre cuando Angular no puede entender qué servicio exactamente debe inyectar en el componente. En este artículo analizaremos todas las causas del error Can't resolve all parameters for component, mostraremos ejemplos prácticos en TypeScript y daremos soluciones paso a paso. No solo corregirás el bug, sino que también entenderás cómo funciona la Inyección de Dependencias (DI) en Angular.
¿Qué es la Inyección de Dependencias y por qué es importante?
Angular está construido sobre el sistema de inyección de dependencias (DI). Cuando escribes:
constructor(private myService: MyService) {}Angular crea automáticamente una instancia de MyService y la pasa al componente. Pero para esto necesita saber tres cosas:
- Qué tipo (clase) debe inyectar.
- Dónde está registrado el proveedor para ese tipo.
- Qué hacer si no hay proveedor.
Si al menos uno de estos puntos no se cumple, obtienes el error «Can't resolve all parameters».
Causas principales del error
Hemos identificado los 5 escenarios más comunes que llevan a este error. Cada uno lo analizaremos con código.
1. El servicio no está registrado en los proveedores
La causa más obvia. Creaste el servicio, pero olvidaste agregarlo en providers del módulo o componente.
Ejemplo de código erróneo:
// my.service.ts@Injectable()export class MyService { getData() { return 'data'; }}
// my.component.ts@Component({ selector: 'app-my', template: '...' })export class MyComponent { constructor(private myService: MyService) {} // ¡Error!}Solución: Registra el servicio en el módulo:
@NgModule({ providers: [MyService] // <-- obligatorio})export class AppModule { }O en el propio componente (si el servicio solo lo necesita él):
@Component({ providers: [MyService]})export class MyComponent { ... }2. Falta el decorador @Injectable()
Incluso si registraste el servicio en los proveedores, pero olvidaste agregar el decorador @Injectable() — Angular no podrá leer los metadatos.
Ejemplo:
// Sin decoradorexport class MyService { ... }
// En el componenteconstructor(private myService: MyService) {} // ¡Error!Solución: Siempre agrega @Injectable():
@Injectable({ providedIn: 'root' }) // o simplemente @Injectable()export class MyService { ... }Por cierto, providedIn: 'root' registra automáticamente el servicio a nivel del inyector raíz — este es el enfoque moderno y recomendado.
3. Conflicto con la compilación AOT y los parámetros del constructor
Angular utiliza dos modos de compilación: JIT (Just-in-Time) y AOT (Ahead-of-Time). El error Can't resolve all parameters ocurre frecuentemente con AOT, si TypeScript no conservó la información sobre los tipos de los parámetros.
Causa: En versiones antiguas de Angular (anteriores a la 5) o al usar ciertas configuraciones de tsconfig, TypeScript podía eliminar los metadatos de tipos. Por ejemplo, si usabas emitDecoratorMetadata: false u olvidabas importar reflect-metadata.
Solución:
- Asegúrate de que en
tsconfig.jsonestén presentes"emitDecoratorMetadata": truey"experimental