rgk
rgk

Reputation: 810

What's the alternative for ResponseType in Angular 5?

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

Answers (3)

rgk
rgk

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

VagrantAI
VagrantAI

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) => { ... }
);

Proof of concept

Upvotes: 1

Estus Flask
Estus Flask

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

Related Questions