Reputation: 876
I have a method on an service to handle all backend requests. Instead of writing a whole bunch of different calls using the HttpClient, I thought I might write one single function that could connect to my backend and pass it arguments to handle different types of data.
Consider this function
public postRequest(token: string, url: string, body: any, headers: Object = {}) : Observable<any> {
//create new header object
const httpOptions = {
headers: new HttpHeaders()
.set('Authorization', token)
};
//add the headers if any
for(let index in headers){
httpOptions.headers.set(index, headers[index]);
}
//connect to the backend and return the repsonse
return this.http.post( this.config.BASE_SERVER_URL + url, body , httpOptions)
.pipe(
map((res) => {
return res;
}),
catchError(this.handleError)
);
}
It works well except I wanted to be able to set the response type dynamically. Thus I could set the method to use one of my model types.
Here's what I'm trying to accomplish. Hopefully this makes sense.
map(res: "Attendee") => {}
//or
map(res: typeof(typeInput)) => {}
Is it possible to pas a "dynamic" type to the http map method so I can map the different responses to a model of my choice?
Upvotes: 0
Views: 1732
Reputation: 1206
I can achieve this by using generic methods.
you can use this approach.
my-own.service.ts
userAuthentication<T>(userName: string, password: string): Observable<T> {
const url = `http://my-own.url`;
const targetData = {
'emailId': userName,
'password': password
};
return this.http.post<CommonResponse<T>>(url, targetData, httpOptions).pipe(
retry(3),
map((data: CommonResponse<T>) => {
if (data.status) {
if (!data.result[0]) {
this.showMessage('You are not authorized for login');
return null;
}
return data.result[0] as T;
}
this.showMessage(data.message);
return null;
}),
tap((userProfile: T) => {
console.log('UserLogin ');
}),
catchError(this.handleError<T>('unable to logged in')));
}
CommonResponse model
export class CommonResponse<T> {
autherizationExpires: string;
autherizationKey: string;
message: string;
result: T | T[];
status: boolean;
}
So, when you call this method like myOwnService.userAuthentication < LoginModel >(...params).subscribe(/ * your codes * /); It will inherited to the map as well.
let me know if I am not get your question.
Upvotes: 3