Angular 4 HttpClient-Abfrageparameter

145

Ich habe nach einer Möglichkeit gesucht, Abfrageparameter an einen API-Aufruf mit den neuen zu übergeben HttpClientModule, HttpClientund habe noch keine Lösung gefunden. Mit dem alten HttpModul würden Sie so etwas schreiben.

getNamespaceLogs(logNamespace) {

    // Setup log namespace query parameter
    let params = new URLSearchParams();
    params.set('logNamespace', logNamespace);

    this._Http.get(`${API_URL}/api/v1/data/logs`, { search: params })
}

Dies würde zu einem API-Aufruf der folgenden URL führen:

localhost:3001/api/v1/data/logs?logNamespace=somelogsnamespace

Die neue HttpClient get()Methode hat jedoch keine searchEigenschaft, sodass ich mich frage, wo ich die Abfrageparameter übergeben soll.

Joshrathke
quelle
2
Mit Angular 7 können Sie Ihre Parameter als Objekt schreiben und wie folgt verwenden : this.httpClient.get(url, { params } Check out stackoverflow.com/a/54211610/5042169
Jun711

Antworten:

229

Am Ende fand ich es über IntelliSense in der get()Funktion. Also werde ich es hier für alle posten, die nach ähnlichen Informationen suchen.

Wie auch immer, die Syntax ist nahezu identisch, aber leicht unterschiedlich. Anstatt URLSearchParams()die Parameter zu verwenden, müssen sie als initialisiert werden HttpParams()und die Eigenschaft innerhalb der get()Funktion wird jetzt paramsanstelle von aufgerufen search.

import { HttpClient, HttpParams } from '@angular/common/http';
getLogs(logNamespace): Observable<any> {

    // Setup log namespace query parameter
    let params = new HttpParams().set('logNamespace', logNamespace);

    return this._HttpClient.get(`${API_URL}/api/v1/data/logs`, { params: params })
}

Eigentlich bevorzuge ich diese Syntax, da sie etwas parameterunabhängiger ist. Ich habe den Code auch überarbeitet, um ihn etwas abgekürzt zu machen.

getLogs(logNamespace): Observable<any> {

    return this._HttpClient.get(`${API_URL}/api/v1/data/logs`, {
        params: new HttpParams().set('logNamespace', logNamespace)
    })
}

Mehrere Parameter

Der beste Weg, den ich bisher gefunden habe, besteht darin, ein ParamsObjekt mit allen Parametern zu definieren, die ich definieren möchte. Wie @estus im Kommentar unten hervorhob, gibt es in dieser Frage viele gute Antworten , wie mehrere Parameter zugewiesen werden können.

getLogs(parameters) {

    // Initialize Params Object
    let params = new HttpParams();

    // Begin assigning parameters
    params = params.append('firstParameter', parameters.valueOne);
    params = params.append('secondParameter', parameters.valueTwo);

    // Make the API call using the new parameters.
    return this._HttpClient.get(`${API_URL}/api/v1/data/logs`, { params: params })

Mehrere Parameter mit bedingter Logik

Eine andere Sache, die ich oft mit mehreren Parametern mache, ist die Verwendung mehrerer Parameter, ohne dass diese bei jedem Aufruf vorhanden sein müssen. Mit Lodash ist es ziemlich einfach, Parameter bedingt zu Aufrufen der API hinzuzufügen / daraus zu entfernen. Die genauen Funktionen, die in Lodash, Underscores oder Vanilla JS verwendet werden, können je nach Anwendung variieren. Ich habe jedoch festgestellt, dass die Überprüfung der Eigenschaftsdefinition recht gut funktioniert. Die folgende Funktion übergibt nur Parameter, die entsprechende Eigenschaften innerhalb der an die Funktion übergebenen Parametervariablen haben.

getLogs(parameters) {

    // Initialize Params Object
    let params = new HttpParams();

    // Begin assigning parameters
    if (!_.isUndefined(parameters)) {
        params = _.isUndefined(parameters.valueOne) ? params : params.append('firstParameter', parameters.valueOne);
        params = _.isUndefined(parameters.valueTwo) ? params : params.append('secondParameter', parameters.valueTwo);
    }

    // Make the API call using the new parameters.
    return this._HttpClient.get(`${API_URL}/api/v1/data/logs`, { params: params })
Joshrathke
quelle
6
Das erste Snippet ist falsch. let params = new HttpParams(); params.set(...)funktioniert nicht wie erwartet. Siehe stackoverflow.com/questions/45459532/…
Estus Flask
@joshrathke Könnten Sie bitte hinzufügen, wie Header und Parameter zusammengefügt werden?
Savad KP
3
@SavadKP Sie können sie so einstellen this.http.get (url, {headers: headers, params: params}); und lesen Sie über neue HttpHeaders wie HttpParams
Junaid
Ich denke, das new HttpParams({fromObject: { param1: 'value1', ... }});ist dann der einfachste Ansatz (Winkel 5+) params.set(...).
Pankaj Prakash
88

Sie können (ab Version 5) die Konstruktorparameter fromObject und fromString verwenden, wenn Sie HttpParamaters erstellen, um die Arbeit zu vereinfachen

    const params = new HttpParams({
      fromObject: {
        param1: 'value1',
        param2: 'value2',
      }
    });

    // http://localhost:3000/test?param1=value1&param2=value2

oder:

    const params = new HttpParams({
      fromString: `param1=${var1}&param2=${var2}`
    });

    //http://localhost:3000/test?paramvalue1=1&param2=value2
JayChase
quelle
27
Dies wird nicht mehr benötigt. Sie können einfach ein JSON-Objekt direkt an HttpClient übergeben. const params = {'key': 'value'}zu: http.get('/get/url', { params: params })
Gefahr89
7
@ Gefahr89 Stimmt. Aber seien Sie gewarnt: Nur String- oder String [] -Werte erlaubt!
Jose Enrique
Ich habe viel Zeit gespart. Ich habe eine URL erstellt, indem ich Abfrageparameter als Zeichenfolge an die Anforderungs-URL angehängt habe.
Pankaj Prakash
16

Sie können es so übergeben

let param: any = {'userId': 2};
this.http.get(`${ApiUrl}`, {params: param})
Pradeep BP
quelle
3
Stimmt, aber das wirft das Tippen aus dem Fenster
DanLatimer
@DanLatimer Sie haben zu einem nicht verwenden, so dass Sie den ganzen Weg halten können mit der Eingabe , bis Sie es passierenparams
InDieTasten
11

Eine präzisere Lösung:

this._Http.get(`${API_URL}/api/v1/data/logs`, { 
    params: {
      logNamespace: logNamespace
    } 
 })
Darwayne
quelle
6

Mit Angular 7 funktionierte es wie folgt, ohne HttpParams zu verwenden.

import { HttpClient } from '@angular/common/http';

export class ApiClass {

  constructor(private httpClient: HttpClient) {
    // use it like this in other services / components etc.
    this.getDataFromServer().
      then(res => {
        console.log('res: ', res);
      });
  }

  getDataFromServer() {
    const params = {
      param1: value1,
      param2: value2
    }
    const url = 'https://api.example.com/list'

    // { params: params } is the same as { params } 
    // look for es6 object literal to read more
    return this.httpClient.get(url, { params }).toPromise();
  }
}
Jun711
quelle
4

Wenn Sie ein Objekt haben, das in {key: 'stringValue'}Paare konvertiert werden kann, können Sie diese Verknüpfung verwenden, um es zu konvertieren:

this._Http.get(myUrlString, {params: {...myParamsObject}});

Ich liebe die Spread-Syntax!

Jeremy Moritz
quelle
3

Joshrathke hat recht.

In angular.io docs wird geschrieben, dass URLSearchParams von @ angle / http veraltet ist . Stattdessen sollten Sie HttpParams von @ angle / common / http verwenden . Der Code ist ziemlich ähnlich und identisch mit dem, was Joshrathke geschrieben hat. Für mehrere Parameter, die beispielsweise in einem Objekt wie gespeichert werden

{
  firstParam: value1,
  secondParam, value2
}

du könntest es auch tun

for(let property in objectStoresParams) {
  if(objectStoresParams.hasOwnProperty(property) {
    params = params.append(property, objectStoresParams[property]);
  }
}

Wenn Sie geerbte Eigenschaften benötigen, entfernen Sie die hasOwnProperty entsprechend.

Sven
quelle
2

Die Sucheigenschaft vom Typ URLSearchParams in der RequestOptions- Klasse ist in Winkel 4 veraltet. Stattdessen sollten Sie die Eigenschaft params vom Typ URLSearchParams verwenden .

Sanket Patel
quelle