Parametry zapytania Angular 4 HttpClient

147

Szukałem sposobu, aby przejść do kwerendy parametry wywołania API z nowym HttpClientModule„s HttpClienti jeszcze się znaleźć rozwiązanie. W starym Httpmodule napisałbyś coś takiego.

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

Spowodowałoby to wywołanie interfejsu API pod następujący adres URL:

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

Jednak nowa HttpClient get()metoda nie ma searchwłaściwości, więc zastanawiam się, gdzie przekazać parametry zapytania?

joshrathke
źródło
2
W Angular 7 możesz zapisać swoje parametry jako obiekt i używać go w następujący sposób: this.httpClient.get(url, { params } Sprawdź stackoverflow.com/a/54211610/5042169
Jun711,

Odpowiedzi:

231

Skończyło się na tym, że znalazłem go za pośrednictwem funkcji IntelliSense get(). Więc opublikuję to tutaj dla każdego, kto szuka podobnych informacji.

W każdym razie składnia jest prawie identyczna, ale nieco inna. Zamiast używać URLSearchParams()parametrów, należy je zainicjować jako, HttpParams()a właściwość w get()funkcji jest teraz wywoływana paramszamiast 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 })
}

Właściwie wolę tę składnię, ponieważ jest trochę bardziej niezależna od parametrów. Zreformowałem również kod, aby był nieco bardziej skrócony.

getLogs(logNamespace): Observable<any> {

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

Wiele parametrów

Najlepszym sposobem, jaki znalazłem do tej pory, jest zdefiniowanie Paramsobiektu ze wszystkimi parametrami, które chcę zdefiniować, zdefiniowanymi w ramach. Jak @estus wskazał w komentarzu poniżej, w tym pytaniu jest wiele świetnych odpowiedzi, jak przypisać wiele parametrów.

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

Wiele parametrów z logiką warunkową

Inną rzeczą, którą często robię z wieloma parametrami, jest zezwolenie na użycie wielu parametrów bez konieczności ich obecności w każdym wywołaniu. Korzystając z Lodash, bardzo łatwo jest warunkowo dodawać / usuwać parametry z wywołań interfejsu API. Dokładne funkcje używane w Lodash, Underscores lub vanilla JS mogą się różnić w zależności od aplikacji, ale zauważyłem, że sprawdzanie definicji właściwości działa całkiem dobrze. Poniższa funkcja przekazuje tylko parametry, które mają odpowiednie właściwości w obrębie zmiennej parametrów przekazanej do funkcji.

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
źródło
6
Pierwszy fragment jest nieprawidłowy. let params = new HttpParams(); params.set(...)nie będzie działać zgodnie z oczekiwaniami. Zobacz stackoverflow.com/questions/45459532/…
Estus Flask
@joshrathke Czy mógłbyś dodać, jak dodać razem nagłówek i parametry?
Savad KP,
3
@SavadKP możesz ustawić je w ten sposób. Http://ttp.get (url, {headers: headers, params: params}); i przeczytaj o nowych HttpHeaders, takich jak HttpParams
Junaid
Myślę, że new HttpParams({fromObject: { param1: 'value1', ... }});jest to najłatwiejsze podejście (kątowe 5+) params.set(...).
Pankaj Prakash
88

Możesz (w wersji 5+) użyć parametrów konstruktora fromObject i fromString podczas tworzenia HttpParamaters, aby trochę ułatwić

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

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

lub:

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

    //http://localhost:3000/test?paramvalue1=1&param2=value2
JayChase
źródło
27
To już nie jest potrzebne. Możesz po prostu przekazać bezpośrednio obiekt JSON do HttpClient. const params = {'key': 'value'}do: http.get('/get/url', { params: params })
niebezpieczeństwo89
7
@ danger89 Prawda. Ale uwaga: dozwolone są tylko wartości typu string lub string []!
Jose Enrique
Zaoszczędziłem ogromną ilość czasu. Tworzyłem adres URL, dołączając parametry zapytania jako ciąg znaków do adresu URL żądania.
Pankaj Prakash
16

Możesz to przekazać w ten sposób

let param: any = {'userId': 2};
this.http.get(`${ApiUrl}`, {params: param})
Pradeep BP
źródło
3
To prawda, ale wyrzuca pisanie przez okno
DanLatimer
@DanLatimer Nie musisz ich używać, więc możesz pisać do końca, dopóki nie przejdziesz doparams
InDieTasten
11

Bardziej zwięzłe rozwiązanie:

this._Http.get(`${API_URL}/api/v1/data/logs`, { 
    params: {
      logNamespace: logNamespace
    } 
 })
Darwayne
źródło
6

W Angular 7 udało mi się go uruchomić, używając następujących elementów bez użycia HttpParams.

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
źródło
4

Jeśli masz obiekt, który można przekształcić w {key: 'stringValue'}pary, możesz użyć tego skrótu, aby go przekonwertować:

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

Po prostu uwielbiam składnię spreadów!

Jeremy Moritz
źródło
3

joshrathke ma rację.

W dokumentach angular.io jest napisane, że URLSearchParams z @ angular / http jest przestarzałe . Zamiast tego powinieneś użyć HttpParams z @ angular / common / http . Kod jest dość podobny i identyczny z tym, co napisał joshrathke. Dla wielu parametrów, które są zapisywane na przykład w obiekcie takim jak

{
  firstParam: value1,
  secondParam, value2
}

możesz też zrobić

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

Jeśli potrzebujesz dziedziczonych właściwości, usuń odpowiednio hasOwnProperty.

Sven
źródło
2

właściwość search typu URLSearchParams w klasie RequestOptions jest przestarzała w wersji kątowej 4. Zamiast tego należy używać właściwości params typu URLSearchParams .

sanket patel
źródło