Reputation:
I am trying to write a Typescript API service. For the service I need a way to check that the method exists when a function such as get
is called.
I realise I can do like
get(endpoint: string) {
this.handleRequest();
}
post(endpoint: string, data: any) {
this.handleRequest();
}
But I don't particularly want to do that are the top of every method so I didn't know if there was a way to listen within the constructor of the Typescript class for a call of a child function.
It seems a little far fetched to be able to do this but it would be extremely useful in cases like mine so I don't have to keep on doing it.
export class ApiService {
base_url: string = 'https://jsonplaceholder.typicode.com/posts';
methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
/**
* Create an instance of ApiService.
* @param {string} base_url
*/
constructor(base_url: string = null) {
this.base_url = base_url ? base_url : this.base_url;
}
get(endpoint: string): string {
// duplicated line
this.handleRequest();
return 'get method';
}
post(endpoint: string, data: any): string {
// duplicated line
this.handleRequest();
return 'post method';
}
protected handleRequest(): string {
return 'handle the request';
}
}
Upvotes: 2
Views: 2947
Reputation: 249586
You can do this using a decorator that will override all methods of the class with a method that calls the original implementation and your extra method:
function handleRequest() {
return function<TFunction extends Function>(target: TFunction){
for(let prop of Object.getOwnPropertyNames(target.prototype)){
if (prop === 'handleRequest') continue;
// Save the original function
let oldFunc: Function = target.prototype[prop];
if(oldFunc instanceof Function) {
target.prototype[prop] = function(){
this['handleRequest'](); // call the extra method
return oldFunc.apply(this, arguments); // call the original and return any result
}
}
}
}
}
@handleRequest()
export class ApiService {
base_url: string = 'https://jsonplaceholder.typicode.com/posts';
methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
/**
* Create an instance of ApiService.
* @param {string} base_url
*/
constructor(base_url: string = null) {
this.base_url = base_url ? base_url : this.base_url;
}
get(endpoint: string): string {
return 'get method';
}
post(endpoint: string, data: any): string {
return 'post method';
}
protected handleRequest(): void {
console.log('handle the request');
}
}
let s = new ApiService();
s.get("");
s.post("", null);
Upvotes: 6