Issue
I have a generic class that uses http inside it:
export abstract class GenericCrudService<T> {
constructor(protected http: HttpService, protected resourse: Resourse) {}
private entities: T[] = [];
entitiesChanged$: Subject<T[]> = new Subject();
getAllEntities() {
this.http.get<T>(environment.endpoint + this.resourse).subscribe((res) => {
this.entities = res;
this.entitiesChanged$.next(this.entities);
});
}
createEntity(entity: T) {
return this.http
.post(environment.endpoint + this.resourse, entity)
.subscribe((_) => {
this.entities.push(entity);
this.entitiesChanged$.next(this.entities);
});
}
deleteEntity(id: string) {
return this.http
.delete(environment.endpoint + this.resourse, id)
.subscribe((res: any) => {
this.entities = this.entities.filter((e: any) => e._id !== res.deleted);
this.entitiesChanged$.next(this.entities);
});
}
updateEntity(id: string, newEntity: T) {
return this.http
.put(environment.endpoint + this.resourse, id, newEntity)
.subscribe((res: any) => {
const updatedIndex = this.entities.findIndex(
(e: any) => e._id === res.updated
);
this.entities[updatedIndex] = newEntity;
this.entitiesChanged$.next(this.entities);
});
}
getLatestEntities() {
return this.entitiesChanged$.asObservable();
}
}
also have this service that extends that class:
@Injectable({
providedIn: "root",
})
export class ExerciseService extends GenericCrudService<IExercise> {
constructor(http: HttpService) {
super(http, Resourse.exercise);
}
}
I thought it would be nicer to not inject the http client in the exercise service as it doesnt need it, and create it only in the generic one by doing something like:
@Inject(HTTP_TOKEN?) http : HttpService and use this.http everywhere in the service. My question is, is it possible and recommended and also if so how can I get the HttpService injection token, or how can I create one if it doesnt exist?
Solution
there is only one "elegant" way to inject anything in Angular and that is the constructor way. The other way is to inject Injector in the constructor and Injector.get(token) at any moment of runtime.
myService = this.injector.get(MyService);
constructor(private injector: Injector) {}
in your code it would be
export abstract class GenericCrudService<T> {
protected http = this.injector.get(HttpService);
constructor(protected injector: Injector, protected resourse: Resourse) {}
...
}
....
export class ExerciseService extends GenericCrudService<IExercise> {
constructor(injector: Injector) {
super(injector, Resourse.exercise);
}
}
then in any descendants you would only pass the injector to parent, and parent may inject whatever it wants with the help of this injector
UPDATE:
it is no longer necessary to inject the Injector
to query all of the dependencies without using constructor. From Angular 14 there is an inject
global function exposed
class SomeComponent {
myService = inject(MyService);
...
Answered By - Andrei
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.