Parâmetros de consulta HttpClient angular 4

147

Fui à procura de uma maneira de passar consulta parâmetros para uma chamada de API com o novo HttpClientModule's HttpCliente ainda têm de encontrar uma solução. Com o Httpmódulo antigo , você escreveria algo assim.

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

Isso resultaria em uma chamada de API para o seguinte URL:

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

No entanto, o novo HttpClient get()método não tem uma searchpropriedade, por isso estou me perguntando para onde passar os parâmetros da consulta?

joshrathke
fonte
2
Com Angular 7, você pode escrever seus parâmetros como um objeto e usá-lo como este: this.httpClient.get(url, { params } Confira stackoverflow.com/a/54211610/5042169
Jun711

Respostas:

231

Acabei encontrando-o através do IntelliSense na get()função. Então, vou postá-lo aqui para quem estiver procurando informações semelhantes.

De qualquer forma, a sintaxe é quase idêntica, mas um pouco diferente. Em vez de usar, URLSearchParams()os parâmetros precisam ser inicializados como HttpParams()e a propriedade dentro da get()função agora é chamada em paramsvez de 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 })
}

Na verdade, eu prefiro essa sintaxe, pois é um pouco mais independente de parâmetro. Também refatorei o código para torná-lo um pouco mais abreviado.

getLogs(logNamespace): Observable<any> {

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

Parâmetros múltiplos

A melhor maneira que eu encontrei até agora é definir um Paramsobjeto com todos os parâmetros que eu quero definir definidos dentro. Como @estus apontou no comentário abaixo, há muitas ótimas respostas nesta pergunta sobre como atribuir vários parâmetros.

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

Vários parâmetros com lógica condicional

Outra coisa que costumo fazer com vários parâmetros é permitir o uso de vários parâmetros sem exigir sua presença em todas as chamadas. Usando o Lodash, é bastante simples adicionar / remover condicionalmente parâmetros de chamadas para a API. As funções exatas usadas no Lodash, no Underscores ou no vanilla JS podem variar dependendo do seu aplicativo, mas eu descobri que a verificação da definição da propriedade funciona muito bem. A função abaixo passará apenas parâmetros que possuem propriedades correspondentes dentro da variável de parâmetros passados ​​para a função.

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
fonte
6
O primeiro trecho está errado. let params = new HttpParams(); params.set(...)não funcionará como esperado. Veja stackoverflow.com/questions/45459532/…
Estus Flask
@joshrathke Você poderia adicionar como adicionar cabeçalho e parâmetros?
precisa
3
@SavadKP, você pode configurá-los assim: this.http.get (url, {headers: headers, params: params}); e leia sobre novos HttpHeaders como HttpParams
Junaid
Eu acho que new HttpParams({fromObject: { param1: 'value1', ... }});é a abordagem mais fácil (angular 5+) então params.set(...).
Pankaj Prakash
88

Você pode (na versão 5+) usar o fromObject e fromString parâmetros do construtor ao criar HttpParamaters para tornar as coisas um pouco mais fácil

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

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

ou:

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

    //http://localhost:3000/test?paramvalue1=1&param2=value2
JayChase
fonte
27
Isso não é mais necessário. Você pode simplesmente passar diretamente um objeto JSON para HttpClient. const params = {'key': 'value'}para: http.get('/get/url', { params: params })
danger89
7
@ danger89 Verdadeiro. Mas esteja avisado: somente valores de string ou string [] são permitidos!
Jose Enrique
Economizei muito tempo. Eu estava construindo o URL anexando parâmetros de consulta como uma string no URL do pedido.
Pankaj Prakash
16

Você pode passar assim

let param: any = {'userId': 2};
this.http.get(`${ApiUrl}`, {params: param})
Pradeep BP
fonte
3
Verdade, mas que lança digitação para fora da janela
DanLatimer
@DanLatimer Você não precisa usar nenhum, portanto, você pode continuar digitando todo o caminho até passar paraparams
InDieTasten
11

Uma solução mais concisa:

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

Com o Angular 7, consegui trabalhar usando o seguinte, sem usar 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
fonte
4

Se você possui um objeto que pode ser convertido em {key: 'stringValue'}pares, pode usar este atalho para convertê-lo:

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

Eu simplesmente amo a sintaxe de propagação!

Jeremy Moritz
fonte
3

Joshrathke está certo.

Em angular.io, o docs está escrito que URLSearchParams de @ angular / http está obsoleto . Em vez disso, você deve usar HttpParams de @ angular / common / http . O código é bastante semelhante e idêntico ao que joshrathke escreveu. Para vários parâmetros salvos, por exemplo, em um objeto como

{
  firstParam: value1,
  secondParam, value2
}

você também poderia fazer

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

Se você precisar de propriedades herdadas, remova o hasOwnProperty adequadamente.

Sven
fonte
2

A propriedade de pesquisa do tipo URLSearchParams na classe RequestOptions está obsoleta no angular 4. Em vez disso, você deve usar a propriedade params do tipo URLSearchParams .

sanket patel
fonte