21

I just made two important upgrades to our Angular 4 application and build tools:

  1. @angular/core ^4.1.3 => ^4.2.4 (and /http, /forms, etc)
  2. tslint ^5.3.2 => ^5.4.3

I have a Service which declares options like so:

@Injectable()
export class WorkOrderService {

    private headers: Headers = new Headers({ 'Content-Type': 'application/json' });
    private options: RequestOptions = new RequestOptions(this.headers);

    constructor(private http: Http) {}

    /* Methods ... */
}

The above now no longer validates tslint, throwing the following error:

error TS2559: Type 'Headers' has no properties in common with type 'RequestOptionsArgs'.

The source (@angular/http interface.d.ts:43) clearly allows for Headers as a RequestOptionsArgs:

/**
 * Interface for options to construct a RequestOptions, based on
 * [RequestInit](https://fetch.spec.whatwg.org/#requestinit) from the Fetch spec.
 *
 * @experimental
 */
export interface RequestOptionsArgs {
    url?: string | null;
    method?: string | RequestMethod | null;
    /** @deprecated from 4.0.0. Use params instead. */
    search?: string | URLSearchParams | {
        [key: string]: any | any[];
    } | null;
    params?: string | URLSearchParams | {
        [key: string]: any | any[];
    } | null;
    headers?: Headers | null;
    body?: any;
    withCredentials?: boolean | null;
    responseType?: ResponseContentType | null;
}
msanford
  • 11,803
  • 11
  • 66
  • 93

1 Answers1

33

Update for 4.3 HttpClient

The new syntax to be compatible with HttpClient, introduced in angular 4.3, is:

import { HttpClient, HttpHeaders } from "@angular/common/http";

private _options = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) };

No more RequestOptions: parameters are added using the new immutable HttpParams Map.

Pre 4.3 / Http

I just noticed that RequestOptions now requires you to explicitly pass named options as an object, like:

headers: Headers = new Headers({ 'Content-Type': 'application/json' });
options: RequestOptions = new RequestOptions({ headers: this.headers });
msanford
  • 11,803
  • 11
  • 66
  • 93
  • 1
    i have being running into similar issue , thank's for providing a solution – Abslen Char Jun 23 '17 at 19:39
  • I think you mightve just needed brackets around your this.headers. new RequestOptions({this.headers}); – LLai Jun 23 '17 at 19:39
  • 2
    @LLai Object destructuring doesn't work in this case because of the *this.*: `Argument of type '{ this: any; }' is not assignable to parameter of type 'RequestOptionsArgs'. Object literal may only specify known properties, and 'this' does not exist in type 'RequestOptionsArgs'.` but I had hoped so, as well. – msanford Jun 23 '17 at 19:44
  • I get HttpHeaders is not exported member of @angular/http, so from where are you importing HttpHeaders? – Akshay Vijay Jain Nov 02 '17 at 18:26
  • 1
    @AkshayVijayJain You're mixing paradigms. `HttpClient` doesn't come from `@angular/http`, it comes from `@angular/common/http`, which is where the rest are exported from as well. Updated the post. – msanford Nov 02 '17 at 18:28
  • 2
    Thank you so much @msanford, however I am getting this error Argument of type '{ headers: HttpHeaders; }' is not assignable to parameter of type 'RequestOptionsArgs'. Types of property 'headers' are incompatible. Type 'HttpHeaders' is not assignable to type 'Headers'. Property 'forEach' is missing in type 'HttpHeaders'.' , when i am requesting like this ---->this.http.post('http://localhost:56451/map', { "username": username, "password": password }, this._options) – Akshay Vijay Jain Nov 02 '17 at 18:29
  • 1
    @AkshayVijayJain My pleasure. Again, you are mixing paradigms. I left `RequestOptionsArgs` in the _second_ part of the post because it no longer applies to `HttpClient`. The two complete code portions are equivalent. If you have a more complex case (such as setting request parameters) I'd post a new question. – msanford Nov 02 '17 at 18:34
  • 1
    yes, you are right, It necessitates a new question, I will post in a minute, however I am unclear about what paradigm what you are talking, any links as to where I can understand what you are referring to – Akshay Vijay Jain Nov 02 '17 at 18:36
  • @msanford, may you please help with following question as per your time https://stackoverflow.com/questions/47082492/how-to-send-post-request-using-http-from-angular-http – Akshay Vijay Jain Nov 02 '17 at 18:46
  • @AkshayVijayJain The paradigm meaning the new `HttpClient` (as of 4.3) or the old `Http` both for making REST requests. They are simply different libraries. – msanford Nov 02 '17 at 19:00
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/158107/discussion-between-akshay-vijay-jain-and-msanford). – Akshay Vijay Jain Nov 02 '17 at 20:05
  • @msanford, sorry if I am making a mistake, but if you take a look at docs https://angular.io/tutorial/toh-pt6#add-the-ability-to-save-hero-details, they have not used HttpClient, but they have used Http instead to send requests -----> saying this because in another answer you have written Http was replaced by HttpClient, is that statement of yours still valid – Akshay Vijay Jain Nov 02 '17 at 20:08
  • 1
    @AkshayVijayJain Yes they probably have. It depends on which version of angular you are using. If it is after 4.3, I suggest using `HttpClient`, see https://angular.io/guide/http – msanford Nov 02 '17 at 20:10
  • 1
    yes, you are right, here is document to show, Http is deprecated https://angular.io/api/http/Http – Akshay Vijay Jain Nov 02 '17 at 20:14
  • 1
    You saved my day. I was following the angular 2 syntax and getting the error. Your solution worked for angular 4 – Nageswara Rao Maridu Nov 22 '17 at 17:05