Mientras trabajo en un programa con el que tengo un problema, el constructor y su inyección de dependencia de su clase secundaria.
constructor(private url: string, private http: Http) { } constructor(http: Http) { super('https://jsonplaceholder.typicode.com/posts', http); }Antes de esta refactorización (mover toda la operación CRUD común y extenderla por clases secundarias), mi código funcionaba como se esperaba, pero DESPUÉS de los cambios anteriores, recibo el siguiente error:
Date: 2020-03-22T15:26:23.248Z - Hash: 7130497a38c152c58258 5 unchanged chunks Time: 1859ms ERROR in src/app/services/data.service.ts:14:23 - error NG2003: No suitable injection token for parameter 'url' of class 'DataService'. Found string 14 constructor(private url: string, private http: Http) { }Además, cuando elimino el parámetro de URL del constructor de Datsource (modifico PostService.ts en consecuencia), la API funciona como se esperaba. ¡No estoy seguro de por qué!
Estoy usando:
CLI angular: 9.0.4 Nodo: 12.16.1 Sistema operativo: win32 x64
Angular: ... Espacio de trabajo Ivy:
@ angular-devkit/arquitecto 0.900.4
@ angular-devkit/core 9.0.4
@angular-devkit/esquemas 9.0.4
@esquemáticos/angular 9.0.4
@schematics/actualización 0.900.4
rxjs 6.5.3
Servicio de datos.ts
import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import { throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { AppError } from '../common/app-error'; import { NotFoundError } from '../common/not-found-error'; import { BadInput } from '../common/bad-input'; @Injectable() export class DataService { // private url = 'https://jsonplaceholder.typicode.com/posts'; constructor(private url: string, private http: Http) { } getAll() { return this.http.get(this.url).pipe(catchError(this.errorHandle)); } create(resource) { return this.http.post(this.url, JSON.stringify(resource)) .pipe(catchError(this.errorHandle)); } update(resource) { return this.http.patch(this.url + '/' + resource.id, JSON.stringify({ isRead: true })) .pipe(catchError(this.errorHandle)); } delete(resource) { return this.http.delete(this.url + '/' + resource.id) .pipe(catchError(this.errorHandle)); } private errorHandle(error: Response){ if (error.status === 404) { return throwError(new NotFoundError()); } if (error.status === 400) { return throwError(new BadInput(error.json())); } return throwError(new AppError(error)); } }PostService.ts
import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import { DataService } from './data.service'; @Injectable() export class PostService extends DataService { constructor(http: Http) { super('https://jsonplaceholder.typicode.com/posts', http); } }eliminar @Injectable() de DataService.ts
Como me encuentro con el mismo error, con la misma notación, creo que ha visto el curso angular 'Mosh' que pertenece a la versión 4.
Hubo varios cambios desde entonces, uno de ellos fue reemplazar Http con HttpClient, otro fue un gran cambio en la biblioteca rxjs, no hace falta decir que sucedió lo mismo con los servicios. Ahora, en lugar de poner sus servicios en proveedores, usa el método @Injectable que creo que es más limpio y más relacionado con el propio servicio.
Sin embargo, si prestó mucha atención a la implementación, notará que DataService es solo una clase base y nunca se usaría como un servicio en sí mismo. Es como un manifiesto. Por lo tanto, no es necesario inyectarlo o proporcionarlo en el módulo de la aplicación. Si puede recordar, 'Mosh' nunca lo proporcionó en el módulo de la aplicación. El único servicio que se proporcionó fue PostService. Es por eso que debe eliminar la decoración @Injectable de DataService.
En DataService.ts :
Actualizar el Constructor.
//import { Inject } from '@angular/core'; constructor(@Inject(String) private url: string, private http: Http)ACTUALIZADO (Explicación):
Según https://angular-2-training-book.rangle.io/di/angular2/inject_and_injectable ;
@Inject() es un mecanismo manual para que Angular sepa que se debe inyectar un parámetro.
El decorador @Inject solo es necesario para inyectar primitivos.
Los tipos primitivos son number, string, boolean, bigint, symbol, null, undefined .
La otra forma ( alternativa ) que se puede usar es:
//import { Inject } from '@angular/core'; @Inject('url') private url: string;