I have an Angular project that uses services that very often repeat themselves with the typical create/read/update/delete/read-list-of-all-entries. I also very often want to manipulate received data in similar ways after receiving it. So I wrote decorators that use apply which "transform" the data in a way determined by the parameter passed to them (the parameter is always an object class).
In normal use this looks like this:
//rule.service.ts
@Injectable({
providedIn: 'root'
})
export class RuleService {
rulesUrl: string = `${Constants.wikiApiUrl}/rule/`;
constructor(private http: HttpClient) {}
@TransformObservable(RuleObject)
getRule(pk: number): Observable<Rule>{
return this.http.get<Rule>(`${this.rulesUrl}/${pk}`);
}
}
This happens a lot, so I want to write a parent-service that I can extend:
//generic-object.service.ts
@Injectable({
providedIn: 'root'
})
export abstract class GenericObjectService{
baseUrl: string;
constructor(
private http: HttpClient,
public objectClass: any,
) {}
@TransformObservable(this.objectClass) //This line won't work
read(pk: number): Observable<any>{
return this.http.get(`${this.baseUrl}/${pk}`);
}
}
The issue is that I can't use "this" for a decorator parameter, it doesn't exist at the time of parsing IIRC. But is there a way I could pass the decorator-parameter to my injected service somehow so that it may be used by the decorator?
Find below also the "TransformObservable" decorator:
export function TransformObservable(modelClass: any){
/**Decorator to apply transformObservableContent */
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor){
const originalMethod = descriptor.value;
descriptor.value = function(){
const observable = originalMethod.apply(this, arguments);
return transformObservableContent(observable, modelClass);
}
return descriptor;
}
}