1

I am trying to create new wrapper for restservice, i am trying to move angular 4 to 5 and upgrading the same service. i get error like below. If i change Observable<Response> to Observable<HttpResponse> also i get error:

Argument of type 'HttpHeaders' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
Property 'headers' is private in type 'HttpHeaders' but not in type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?:

below is code.

import { Injectable } from '@angular/core';    
import { Observable } from 'rxjs/Observable';    
import { HttpClient, HttpRequest, HttpHeaders, HttpResponse } from '@angular/common/http';

@Injectable()
export class httpService {
    private requestHeaders: HttpHeaders;

    constructor(private _http: HttpClient) {
        this.requestHeaders = new HttpHeaders();
        this.requestHeaders.append('Content-Type', 'application/json');
        this.requestHeaders.append('Accept', 'application/json');
    }

    post(url: string, requestData?: any): Observable<Response> {
        return this._http.post(url, requestData, this.requestHeaders);
    }
}

Above is fixed by using {headers: this.requestHeaders}

but while line return this._http.post(url, requestData, this.requestHeaders); throws error like

Type 'Observable<ArrayBuffer>' is not assignable to type 'Observable<Response>'.
Type 'ArrayBuffer' is not assignable to type 'Response'.
Property 'body' is missing in type 'ArrayBuffer'.
4
  • There's no Observable<Response> as a return type of httpClient.get. You can either use Observable<any> or Observable<HttpResponse<any>> . Commented Dec 6, 2017 at 19:43
  • It is an http.post method Commented Dec 6, 2017 at 19:47
  • They have the same return types (even their overloads). Commented Dec 6, 2017 at 19:56
  • Observable<HttpResponse<any>> did not work just any works. Commented Dec 7, 2017 at 2:36

2 Answers 2

4

headers is only one parameter of the options, so you should be passing in

{headers: this.requestHeaders}

This will also fix the Property 'headers' is private... error you are seeing.


Also, HttpHeaders is immutable. So every mutation operator returns a new instance. This means to properly set the headers you will need to do

this.requestHeaders = new HttpHeaders()
    .append('Content-Type', 'application/json')
    .append('Accept', 'application/json');

or

this.requestHeaders = new HttpHeaders();
this.requestHeaders = this.requestHeaders.append('Content-Type', 'application/json');
this.requestHeaders = this.requestHeaders.append('Accept', 'application/json');

Updated:

So the post observable is returning of type Observable<ArrayBuffer> but your method is declared to return type Observable<Response> causing the type mismatch. The HttpClient expects you to pass in the return type to the method this.http.post<YourResponseType>(...) (or it will assume the return type). So your method should be updated to

post<T>(url: string, requestData?: any): Observable<T> {
    return this.http.post<T>(url, requestData, {headers: this.requestHeaders});
}

where T is the response type. Now the http method is expecting to return type Observable<T> and your post method is returning type Observable<T>. The types match. You would use your method like so

this.post<MyResponse>(myUrl, myRequestData).subscribe(...);
Sign up to request clarification or add additional context in comments.

6 Comments

Can you look at new error i am getting. Updated the question.
@Hacker you still want the T syntax. You would only return HttpResponse if you passed in {observe: 'response'} to the options. If you were to pass in that parameter then you could pass in <HttpResponse<MyResponse>> to your post method this.post<HttpResponse<MyResponse>>.subscribe(...);
Just wondering how the method post(url: string, requestData?: any): Observable<Response> { return this._http.post(url, requestData, this.requestHeaders); be updated the clear the issue. }
@Hacker I'm not sure what you are asking. The HttpClient methods (get, post, put, etc..) do not return type Response like the old Http methods. Instead it assumes that json is being returned. That is why you pass in your desired response type this.post<YourResponseType>(). The HttpClient will parse the response and say it is of type YourResponse.
@Hacker that is where T comes into play. It is called a generic. Your global function should return Observable<T>, so when you pass in this.post<MyResponseType>() T = MyResponseType
|
1

The implementation of append() is:

append(name: string, value: string|string[]): HttpHeaders { 
   return this.clone({name, value, op: 'a'}); 
 } 

It returns a clone of hte headers object. You need to store/assign the returned result to your variable this.reqequestHeaders otherwise it would not be saved.

Alternatively, the constructor os HttpHeaders is:

constructor(headers?: string|{[name: string]: string | string[]})

A cleaner way to do is:

const headerJson = {
  'Content-Type': 'application/json',
  'Accept' : 'application/json'
}

this.header = new HttpHeaders(headerJson);

4 Comments

The header private variable should be of any type?
header: HttpHeaders and also set return type for your post method: post():Observable<any> {...}
So Observable<any> is only option i can set over there for post().
@Hacker by using any you lose the ability to strictly type your response

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.