First of all, my Typescript knowledge is very low, so I assume that this is a somewhat basic question. In the frontend of my web application, there are two parameters which I need to provide in 99% of all http get-requests. To make my life a little bit easier, I decided to write a simple wrapper around HttpClient
(from "@angular/common/http") which provides these params for me. All I need to pass to it is an object from which it then reads those two parameters and adds them to the parameters of the get-request. Here is how this code currently looks like:
public get<T>(url: string, additionalObj?: AdditionalObject) {
if (additionalObj == null) {
return this.http.get<T>(url, {
headers: {
"Content-Type": "application/json",
},
});
} else {
const params: Record<string, string> = {};
const param1: string | undefined = additionalObj?.param1;
const param2: string | undefined = additionalObj?.param2;
if (param1) {
params["param1"] = param1;
}
if (param2) {
params["param2"] = param2;
}
return this.http.get<T>(url, {
headers: {
"Content-Type": "application/json",
},
params,
});
}
}
While this works just fine in most cases, I also have some functions which need to provide even more params to the get-request, so I need some way to merge the params provided to my function with the two params which I provide inside the function, but I don't know how to do that. I do not want to change anything in the functions which already call my function but I also want to provide a way to specify additional params if necessary. How can I do that?
I think your implementation might be overcomplicated for what you need. I would also look at using Http Interceptors if you're using Angular.
There are a couple of confusing things, you always provide the 2 parameters, but the first branch on your if statement (additionalObj == null)
won't use those values? If we make the assumption that you are after technically three branches
You can achieve with the following.
Use a helper function to retrieve all keys from a given object and populate a given record. This will save on if (param1)
type scenarios.
GetParams(obj: any, params: Record<string, string>): Record<string, string>{
for (const p of Object.keys(obj)){
if(p){
params[p] = obj[p];
}
}
return params;
}
With your wrapper you can alter it as so:
public get<T>(url: string, additionalObj?: AdditionalObject) {
if (additionalObj == null) {
return this.http.get<T>(url, {
headers: {
"Content-Type": "application/json",
},
});
} else {
let params: Record<string, string> = GetParams(additionalObj, {});
return this.http.get<T>(url, {
headers: {
"Content-Type": "application/json",
},
params,
});
}
}
}
This will get you into the same position as you were, but with slightly cleaner and scalable use
Now to add additional parameters, you have two options,
AdditionalObject
properties. If it's too much to change the object, you can slightly change your function's signature for type safety. All you need to do is add the extra parameters to your additionalObj
.public get<T>(url: string, additionalObj?: Partial<AdditionalObject>)
You can add another object to the function call and take those properties.
public get<T>(url: string, additionalObj?: Partial<AdditionalObject>, evenMoreParams?: any) {
if (additionalObj == null) {
return this.http.get<T>(url, {
headers: {
"Content-Type": "application/json",
},
});
} else {
let params: Record<string, string> = GetParams(additionalObj, {});
params = GetParams(evenMoreParams, params);
return this.http.get<T>(url, {
headers: {
"Content-Type": "application/json",
},
params,
});
}
}
}