web-dev-qa-db-fra.com

Angular 4/5 HttpClient: l'argument de type chaîne n'est pas assignable à 'body'

Les docs Angular angulaires disent:

Le corps de la réponse ne renvoie pas toutes les données dont vous pourriez avoir besoin. Parfois, les serveurs renvoient des en-têtes ou des codes d’état spéciaux pour indiquer certaines conditions, et leur vérification peut être nécessaire. Pour ce faire, vous pouvez indiquer à HttpClient que vous voulez la réponse complète au lieu du corps avec l'option observer:

http
  .get<MyJsonData>('/data.json', {observe: 'response'})
  .subscribe(resp => {
    // Here, resp is of type HttpResponse<MyJsonData>.
    // You can inspect its headers:
    console.log(resp.headers.get('X-Custom-Header'));
    // And access the body directly, which is typed as MyJsonData as requested.
    console.log(resp.body.someField);
  });

Mais quand j'essaye ça, j'obtiens une erreur de compilation (pas d'erreurs d'exécution, ça fonctionne comme prévu):

erreur TS2345: argument de type '{en-têtes: HttpHeaders; observer: chaîne; } 'n'est pas assignable à un paramètre de type' {en-têtes ?: HttpHeaders | {[en-tête: chaîne]: chaîne | chaîne[]; }; observer ?: "corps"; params ?: Ht ... '. Les types de propriété 'observer' sont incompatibles. Le type 'chaîne' n'est pas assignable au type '"corps"'.

Pourquoi? J'utilise "@angular/http": "^5.1.0"

Voici ma version du code:

  login(credentials: Credentials): Observable<any> {
    const options = {
      headers: new HttpHeaders({'Content-Type': 'application/json'}),
      observe: 'response'
    };
    return this.httpClient.post<any>(`${environment.USER_SERVICE_BASE_URL}`,
      {'username': credentials.username, 'password': credentials.password}, options)
      .map((res) => ...
15
Phil

Vous devez intégrer les options. Voir ticket github # 18586 , entrée de alxhub le 9 août 2017.

TypeScript doit pouvoir déduire les valeurs observe et responseType de manière statique, afin de choisir le type de retour correct pour get (). Si vous transmettez un objet options incorrectement typé, il ne peut pas déduire le type de retour correct.

login(credentials: Credentials): Observable<any> {
    return this.httpClient.post<any>(`${environment.USER_SERVICE_BASE_URL}`,
      {'username': credentials.username, 'password': credentials.password}, {
      headers: new HttpHeaders({'Content-Type': 'application/json'}),
      observe: 'response'
    })
      .map((res) => ...
31
Igor

TypeScript se plaint de ce problème

Le type 'chaîne' n'est pas assignable au type "body"

Pour résoudre ce problème, convertissez la chaîne en corps manuellement. Exemple:

    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json'
      }),
      observe: 'response' as 'body'
    };
    return this.http.post<any>(url, data, httpOptions);
19

La façon dont j'ai réussi à contourner ce problème, sans aligner les options (ce qui peut conduire à un code moins net) a été de créer une interface pour les options de requête. Le code ressemble à ceci:

export interface IRequestOptions {
    body?: any;
    headers?: HttpHeaders | { [header: string]: string | Array<string> };
    observe?: any;
    params?: HttpParams | { [param: string]: string | Array<string> };
    reportProgress?: boolean;
    responseType?: "arraybuffer" | "blob" | "json" | "text";
    withCredentials?: boolean;
}

Ensuite, ceci est utilisé comme tel:

const options: IRequestOptions = {
    headers: new HttpHeaders({"Content-Type": "application/json"}),
    observe: "response"
};
return this.httpClient.post(`${environment.USER_SERVICE_BASE_URL}`,
    {"username": credentials.username, "password": credentials.password}, options)
    .pipe(
        map((res: HttpResponse<any>) => ...
    );

Changer pour le message d'origine d'utiliser lettable ou pipeable (quel que soit le nom du nom actuel) (opérateurs)

9
blo0p3r