Parámetros de consulta angular 4 HttpClient

147

He estado buscando una manera de pasar consulta parámetros en una llamada a la API con el nuevo HttpClientModule's HttpClient, y todavía tengo que encontrar una solución. Con el antiguo Httpmódulo escribirías algo como esto.

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

Esto resultaría en una llamada API a la siguiente URL:

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

Sin embargo, el nuevo HttpClient get()método no tiene una searchpropiedad, por lo que me pregunto dónde pasar los parámetros de consulta.

joshrathke
fuente
2
Con Angular 7, puede escribir sus parámetros como un objeto y usarlo así: this.httpClient.get(url, { params } Consulte stackoverflow.com/a/54211610/5042169
Jun711

Respuestas:

231

Terminé encontrándolo a través de IntelliSense en la get()función. Entonces, lo publicaré aquí para cualquiera que esté buscando información similar.

De todos modos, la sintaxis es casi idéntica, pero ligeramente diferente. En lugar de usar URLSearchParams()los parámetros, debe inicializarse como HttpParams()y get()ahora se llama a la propiedad dentro de la función en paramslugar 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 })
}

De hecho, prefiero esta sintaxis ya que es un poco más agnóstico de parámetros. También refactoricé el código para hacerlo un poco más abreviado.

getLogs(logNamespace): Observable<any> {

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

Parámetros Múltiples

La mejor manera que he encontrado hasta ahora es definir un Paramsobjeto con todos los parámetros que quiero definir definidos dentro. Como @estus señaló en el comentario a continuación, hay muchas respuestas excelentes en esta pregunta sobre cómo asignar múltiples 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 })

Parámetros múltiples con lógica condicional

Otra cosa que a menudo hago con múltiples parámetros es permitir el uso de múltiples parámetros sin requerir su presencia en cada llamada. Con Lodash, es bastante simple agregar / eliminar condicionalmente los parámetros de las llamadas a la API. Las funciones exactas utilizadas en Lodash o Underscores, o vanilla JS pueden variar según su aplicación, pero descubrí que verificar la definición de propiedad funciona bastante bien. La siguiente función solo pasará parámetros que tengan propiedades correspondientes dentro de la variable de parámetros pasada a la función.

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
fuente
66
El primer fragmento está mal. let params = new HttpParams(); params.set(...)No funcionará como se esperaba. Ver stackoverflow.com/questions/45459532/…
Estus Flask
@joshrathke ¿Podría agregar cómo agregar encabezado y parámetros juntos?
Savad KP
3
@SavadKP puede configurarlos así this.http.get (url, {encabezados: encabezados, params: params}); y lea sobre nuevos HttpHeaders como HttpParams
Junaid
Supongo que new HttpParams({fromObject: { param1: 'value1', ... }});es el enfoque más fácil (angular 5+) entonces params.set(...).
Pankaj Prakash
88

Puede (en la versión 5+) usar los parámetros del constructor fromObject y fromString al crear HttpParamaters para facilitar las cosas

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

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

o:

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

    //http://localhost:3000/test?paramvalue1=1&param2=value2
JayChase
fuente
27
Esto ya no es necesario. Puede pasar directamente un objeto JSON a HttpClient. const params = {'key': 'value'}a: http.get('/get/url', { params: params })
danger89
77
@ danger89 Cierto. Pero tenga cuidado: ¡solo se permiten los valores de cadena o cadena []!
José Enrique
Ahorré gran cantidad de mi tiempo. Estaba construyendo url agregando parámetros de consulta como cadena a la url de solicitud.
Pankaj Prakash
16

Puedes pasarlo así

let param: any = {'userId': 2};
this.http.get(`${ApiUrl}`, {params: param})
Pradeep BP
fuente
3
Es cierto, pero eso arroja escribir por la ventana
DanLatimer
@DanLatimer No tienes que usar ninguno, así que puedes seguir escribiendo todo el tiempo hasta que lo pases aparams
InDieTasten
11

Una solución más concisa:

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

Con Angular 7, lo hice funcionar usando lo siguiente sin 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
fuente
4

Si tiene un objeto que se puede convertir en {key: 'stringValue'}pares, puede usar este acceso directo para convertirlo:

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

¡Me encanta la sintaxis extendida!

Jeremy Moritz
fuente
3

joshrathke tiene razón.

En angular.io docs está escrito que URLSearchParams de @ angular / http está en desuso . En su lugar, debe usar HttpParams de @ angular / common / http . El código es bastante similar e idéntico a lo que joshrathke ha escrito. Para múltiples parámetros que se guardan, por ejemplo, en un objeto como

{
  firstParam: value1,
  secondParam, value2
}

también podrías hacer

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

Si necesita propiedades heredadas, elimine hasOwnProperty en consecuencia.

Sven
fuente
2

la propiedad de búsqueda de tipo URLSearchParams en la clase RequestOptions está en desuso en angular 4. En su lugar, debe usar la propiedad params de tipo URLSearchParams .

sanket patel
fuente