Reputation: 810
I am trying to rewrite a wrapper for http requests using generics. Before Angular 5 there is Observable<responseType>
is available. I am looking for alternative for generic responseType. My code is as follows.
request(endpoint: string, options?: RequestOptions, apiOptions?: IApiServiceOptions): Observable<any> {
options = options || {method: 'GET'};
apiOptions = apiOptions || {};
// build url
const url = `${this.baseUrl}${endpoint}`;
this.log.debugApiCall(url, this.source, options);
// set headers
const authToken = this.authStorage.getAuthenticationToken(this.service);
let headers = new HttpHeaders();
if (authToken) {
headers = headers.set('Authorization', `Bearer ${authToken.jwtToken}`);
}
headers = headers.set('Content-Type', 'application/json');
options.headers = headers;
// make request and handle errors
return this
.http
.request(options.method, url, options)
.do((req) => {
this.log.debugApiResponse(url, this.source, req);
})
.catch((res: HttpErrorResponse) => {
switch (res.status) {
case 0:
this.log.error(res, `>>server down<<: ${res} - if the server is up, make sure this isn't a CORS error`);
this._serverDown$.next();
return Observable.throw(res);
case 401:
this.log.debug(`authentication error: ${res}`);
if (!apiOptions.disableServerDown) {
this._authError$.next(authToken);
} else {
this.log.debug('authError$ not emitted since apiOptions.disableServerDown === true');
}
return Observable.throw(res);
default:
this.log.error(res, 'Unexpected Error');
return Observable.throw(res);
}
});
}
get(url: string, options?: RequestOptions, apiOptions?: IApiServiceOptions): Observable<any> {
options = options || {};
options.method = 'GET';
return this.request(url, options, apiOptions);
}
post(url: string, body: any, options?: RequestOptions, apiOptions?: IApiServiceOptions): Observable<any> {
options = options || {};
options.method = 'POST';
options.body = body;
return this.request(url, options, apiOptions);
}
put(url: string, body: any, options?: RequestOptions, apiOptions?: IApiServiceOptions): Observable<any> {
options = options || {};
options.method = 'PUT';
options.body = body;
return this.request(url, options, apiOptions);
}
However, the return type of request method is Observable<HttpResponse<T>>
. What should be the value of T in general ? I ended up with any as of now.
Any suggestions on this?
Upvotes: 0
Views: 1414
Reputation: 810
How about this.
export type ResponseData = ArrayBuffer | Blob | string;
export type RequestResponse = Observable<ResponseData | Object | any
| HttpEvent<ResponseData | any>
| HttpResponse<ResponseData | Object>>;
request(endpoint: string, options?: IRequestOptions, apiOptions?: IApiServiceOptions): Observable<RequestResponse> {
............
Upvotes: 1
Reputation: 670
According to Angular HTTP client documentation and Typescript generics, you can use generic type in between of function name and its arguments in http requests. E.g. taking your get
function as example, your code would look like this
get<T>(url: string, options?: RequestOptions, apiOptions?: IApiServiceOptions): Observable<T> {
options = options || {};
options.method = 'GET';
return this.request<T>(url, options, apiOptions);
}
Notice where generic type <T>
was added. Then you can simply call your function via next line
someHttpServiceInstance.get<SomeClass>(...some arguments).subscribe(
(output: SomeClass) => { ... }
);
Upvotes: 1
Reputation: 222334
Although HttpClient
documentation doesn't reflect that and uses any
, request
and other methods are already typed and allow for generic types. Method signatures depend on responseType
and observe
options as it would be expected, because the result depends on them.
Upvotes: 0