web-dev-qa-db-fra.com

Angular 4.3.3 HttpClient: Comment obtenir une valeur de l'en-tête d'une réponse?

(Editeur: VS Code; TypeScript: 2.2.1)

Le but est d'obtenir les en-têtes de la réponse de la demande

Supposons une demande POST avec HttpClient dans un service 

import {
    Injectable
} from "@angular/core";

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

@Injectable()
export class MyHttpClientService {
    const url = 'url';

    const body = {
        body: 'the body'
    };

    const headers = 'headers made with HttpHeaders';

    const options = {
        headers: headers,
        observe: "response", // to display the full response
        responseType: "json"
    };

    return this.http.post(sessionUrl, body, options)
        .subscribe(response => {
            console.log(response);
            return response;
        }, err => {
            throw err;
        });
}

Documentation angulaire HttpClient

Le premier problème est que j'ai une erreur TypeScript:

'Argument of type '{ 
    headers: HttpHeaders; 
    observe: string; 
    responseType: string;
}' is not assignable to parameter of type'{ 
    headers?: HttpHeaders;
    observe?: "body";
    params?: HttpParams; reportProgress?: boolean;
    respons...'.

Types of property 'observe' are incompatible.
Type 'string' is not assignable to type '"body"'.'
at: '51,49' source: 'ts'

En effet, quand je vais à la méthode ref () de post (), je pointe sur ce prototype (I Use VS code)

post(url: string, body: any | null, options: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType: 'arraybuffer';
        withCredentials?: boolean;
    }): Observable<ArrayBuffer>;

Mais je veux cette méthode surchargée:

post(url: string, body: any | null, options: {
    headers?: HttpHeaders;
    observe: 'response';
    params?: HttpParams;
    reportProgress?: boolean;
    responseType?: 'json';
    withCredentials?: boolean;
}): Observable<HttpResponse<Object>>;

J'ai donc essayé de corriger cette erreur avec cette structure:

  const options = {
            headers: headers,
            "observe?": "response",
            "responseType?": "json",
        };

Et ça compile! Mais je viens de recevoir la demande de corps au format JSON.

De plus, pourquoi je dois mettre un? symbole à la fin du nom des champs? Comme je l'ai vu sur le site TypeScript, ce symbole devrait simplement indiquer à l'utilisateur qu'il est facultatif?

J'ai aussi essayé d'utiliser tous les champs, sans et avec? des notes

MODIFIER 

J'ai essayé les solutions proposées par Angular 4 obtenir des en-têtes de réponse API . Pour la solution cartographique:

this.http.post(url).map(resp => console.log(resp));

Le compilateur TypeScript indique que la carte n'existe pas car elle ne fait pas partie de Observable

J'ai aussi essayé ça

import { Response } from "@angular/http";

this.http.post(url).post((resp: Response) => resp)

Il compile, mais je reçois une réponse de type de média non prise en charge . Ces solutions devraient fonctionner pour "Http" mais pas pour "HttpClient".

EDIT 2

J'obtiens également un type de support non pris en charge avec la solution @Supamiu. Ce serait donc une erreur sur mes en-têtes. Ainsi, la deuxième solution ci-dessus (avec type de réponse) devrait également fonctionner. Mais personnellement, je ne pense pas que ce soit un bon moyen de mélanger "Http" avec "HttpClient", je vais donc conserver la solution de Supamiu.

37
M.Lobry

Vous pouvez observer la réponse complète au lieu du contenu uniquement:

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);
  });

Voir Documentation HttpClient

74
Supamiu

En effet, le problème principal était un problème de TypeScript.

Dans le code de post (), les options ont été déclarées directement dans les paramètres, donc en tant qu’interface "anonyme".

La solution a été de mettre directement les options brutes dans les paramètres

http.post("url", body, {headers: headers, observe: "response"}).subscribe...
13
M.Lobry

problème principal du transtypage afin que nous puissions utiliser "réponse" comme "corps"

nous pouvons gérer comme

const options = {
    headers: headers,
    observe: "response" as 'body', // to display the full response & as 'body' for type cast
    responseType: "json"
};

return this.http.post(sessionUrl, body, options)
    .subscribe(response => {
        console.log(response);
        return response;
    }, err => {
        throw err;
    });
13
Birbal Singh

Si vous utilisez la solution de la première réponse et que vous n'avez pas accès à .keys() ou .get() sur response.headers, assurez-vous d'utiliser fetch plutôt que xhr. 

Les demandes de récupération sont les demandes par défaut, mais Angular utilisera xhr si des en-têtes réservés à xhr sont présents (e.x. x-www-form-urlencoded).

Si vous essayez d'accéder à des en-têtes de réponse personnalisés, vous devez spécifier ces en-têtes avec un autre en-tête appelé Access-Control-Expose-Headers .

0
Man Personson