let httpParams = new HttpParams().set('aaa', '111');
httpParams.set('bbb', '222');

¿Por qué no funciona?
Es sólo el conjunto de la ‘aaa’ y NO la ‘bbb’

También, tengo un objeto { aaa: 111, bbb: 222 }
¿Cómo puedo establecer todos los valores sin bucle?

ACTUALIZACIÓN (esto parece funcionar, pero ¿cómo se puede evitar el bucle?)

let httpParams = new HttpParams();
Object.keys(data).forEach(function (key) {
     httpParams = httpParams.append(key, data[key]);
});
  • Estoy de acuerdo con usted en que httpParams.set('bbb', '222'); debería funcionar. Traté de que la primera y estaba muy confundida. Pero sustituir a la línea con httpParams = httpParams.set('bbb','222'); obras. para los que sólo la opción 2, el encadenamiento de respuesta de otro Usuario de abajo es también agradable.
  • sólo el uso de asignación (=) como @AngelaPan ha sugerido y usted no tiene que usar un bucle. También leer sobre mutable e inmutable.
  • por favor vote por el condicional HttpParams conjunto de características de la actualización: github.com/angular/angular/issues/26021
InformationsquelleAutor Michalis | 2017-07-20

12 Comentarios

  1. 67

    Antes de 5.0.0-beta.6

    let httpParams = new HttpParams();
    Object.keys(data).forEach(function (key) {
         httpParams = httpParams.append(key, data[key]);
    });
    

    Desde 5.0.0-beta.6

    Desde 5.0.0-beta.6 (2017-09-03) que añaden nuevas características (aceptar mapa del objeto HttpClient para los encabezados & params)

    Adelante el objeto puede ser pasado directamente en lugar de HttpParams.

    getCountries(data: any) {
        //We don't need any more these lines
        //let httpParams = new HttpParams();
        //Object.keys(data).forEach(function (key) {
        //    httpParams = httpParams.append(key, data[key]);
        //});
    
        return this.httpClient.get("/api/countries", {params: data})
    }
    
    • Estoy usando 5.2.6 y definitivamente no tomar un diccionario para los parámetros de la pieza, a menos que me explícitamente caso a any. Es que realmente la intención de uso?
    • usted sólo puede emitir su objeto a cualquier { params: <any>params } para evitar ts compilador emite
    • Parámetros de tipo string que son nulos devolverá «null» y no admite Número, Booleano, Fecha
    • Aquí hay un enlace al informe de error por la falta de Número, Booleano y la ayuda de la Fecha: github.com/angular/angular/issues/23856
  2. 63

    HttpParams es la intención de ser inmutable. El set y append métodos no modificar la instancia existente. En lugar de devolver una nueva instancia, con los cambios aplicados.

    let params = new HttpParams().set('aaa', 'A');    //now it has aaa
    params = params.set('bbb', 'B');                  //now it has both
    

    Este enfoque funciona bien con el método de encadenamiento:

    const params = new HttpParams()
      .set('one', '1')
      .set('two', '2');
    

    …a pesar de que podría ser difícil si usted necesita para envolver a cualquiera de ellos en condiciones.

    Su bucle funciona porque estás agarrando una referencia a la volvió nueva instancia. El código que has publicado que no funciona, no. Llama set() pero no agarra el resultado.

    let httpParams = new HttpParams().set('aaa', '111'); //now it has aaa
    httpParams.set('bbb', '222');                        //result has both but is discarded
    
  3. 35

    En las versiones más recientes de @angular/common/http (5.0 y superiores, por lo que se ve), puede utilizar el fromObject clave de HttpParamsOptions para pasar el objeto directamente en:

    let httpParams = new HttpParams({ fromObject: { aaa: 111, bbb: 222 } });

    Esto sólo se ejecuta una forEach bucle bajo el capó, a pesar de que:

    this.map = new Map<string, string[]>();
    Object.keys(options.fromObject).forEach(key => {
      const value = (options.fromObject as any)[key];
      this.map !.set(key, Array.isArray(value) ? value : [value]);
    });
  4. 18

    Como para mí, el encadenamiento de set métodos es la forma más limpia

    const params = new HttpParams()
    .set('aaa', '111')
    .set('bbb', "222");
    
    • HttpParams es inmutable como HttpHeaders, lo que significa que la segunda .llamada set() no funciona en este caso. Se debe establecer en un hit o se va con el .método append() de la asignación de la salida a una nueva variable como el OP sugirió en su actualización.
    • Sólo traté de Mike encadenamiento de conjunto. y que hace el trabajo! Creo que es bonito que la gente que sólo tiene 2 parámetros. Es fácil de entender.
  5. 12

    Par de Alternativas Fáciles

    Sin usar HttpParams Objetos

    let body = {
       params : {
        'email' : emailId,
        'password' : password
       }
    }
    
    this.http.post(url, body);
    

    Utilizando HttpParams Objetos

    let body = new HttpParams({
      fromObject : {
        'email' : emailId,
        'password' : password
      }
    })
    
    this.http.post(url, body);
    
  6. 7

    Desde HTTP Params clase es inmutable, por tanto, necesita de la cadena de la
    método de juego:

    const params = new HttpParams()
    .set('aaa', '111')
    .set('bbb', "222");
    
  7. 5

    El uso de este se puede evitar el bucle.

    //obj is the params object with key-value pair. 
    //This is how you convert that to HttpParams and pass this to GET API. 
    
    const params = Object.getOwnPropertyNames(obj)
                   .reduce((p, key) => p.set(key, obj[key]), new HttpParams());
    

    Además, sugiero hacer toHttpParams función en la que comúnmente se utiliza el servicio. Así que usted puede llamar a la función para convertir el objeto a la HttpParams.

    /**
     * Convert Object to HttpParams
     * @param {Object} obj
     * @returns {HttpParams}
     */
    toHttpParams(obj: Object): HttpParams {
        return Object.getOwnPropertyNames(obj)
            .reduce((p, key) => p.set(key, obj[key]), new HttpParams());
    }
    

    Actualización:

    Desde 5.0.0-beta.6 (2017-09-03) que añaden nuevas características (aceptar
    mapa del objeto HttpClient para los encabezados & params
    )

    Adelante el objeto puede ser pasado directamente en lugar de HttpParams.

    Esta es la otra razón, si usted ha utilizado una función común, como toHttpParams se mencionó anteriormente, usted puede fácilmente eliminar o hacer cambios si es necesario.

    • Hola su trabajo bien, pero anexar extra indefinido valor de la clave como param
  8. 2

    Tan lejos como puedo ver desde la aplicación en https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts

    Debe proporcionar valores por separado – Que no son capaces de evitar el bucle.

    También hay un constructor que toma una cadena como parámetro, pero es en forma param=value&param2=value2 así que no hay problema para Usted (en ambos casos usted va a terminar con la colocación de su objeto).

    Siempre se puede informar de un problema/función de solicitud para angular, lo que yo recomiendo:
    https://github.com/angular/angular/issues

    PD: Recordar acerca de la diferencia entre set y append métodos 😉

  9. 1

    Ya que @MaciejTreder confirmado que tenemos a bucle, he aquí un contenedor que, opcionalmente, permite agregar a un conjunto predeterminado de parámetros:

    function genParams(params: object, httpParams = new HttpParams()): object {
        Object.keys(params)
            .filter(key => {
                let v = params[key];
                return (Array.isArray(v) || typeof v === 'string') ? 
                    (v.length > 0) : 
                    (v !== null && v !== undefined);
            })
            .forEach(key => {
                httpParams = httpParams.set(key, params[key]);
            });
        return { params: httpParams };
    }
    

    Se puede utilizar como así:

    const OPTIONS = {
        headers: new HttpHeaders({
            'Content-Type': 'application/json'
        }),
        params: new HttpParams().set('verbose', 'true')
    };
    let opts = Object.assign({}, OPTIONS, genParams({ id: 1 }, OPTIONS.params));
    this.http.get(BASE_URL, opts); //--> ...?verbose=true&id=1
    
  10. 0

    Mi clase auxiliar (ts) para convertir cualquier complejo dto objeto (no sólo «diccionario de cadenas») a HttpParams:

    import { HttpParams } from "@angular/common/http";
    
    export class HttpHelper {
      static toHttpParams(obj: any): HttpParams {
        return this.addToHttpParams(new HttpParams(), obj, null);
      }
    
      private static addToHttpParams(params: HttpParams, obj: any, prefix: string): HttpParams {    
        for (const p in obj) {
          if (obj.hasOwnProperty(p)) {
            var k = p;
            if (prefix) {
              if (p.match(/^-{0,1}\d+$/)) {
                k = prefix + "[" + p + "]";
              } else {
                k = prefix + "." + p;
              }
            }        
            var v = obj[p];
            if (v !== null && typeof v === "object" && !(v instanceof Date)) {
              params = this.addToHttpParams(params, v, k);
            } else if (v !== undefined) {
              if (v instanceof Date) {
                params = params.set(k, (v as Date).toISOString()); //serialize date as you want
              }
              else {
                params = params.set(k, v);
              }
    
            }
          }
        }
        return params;
      }
    }
    
    console.info(
      HttpHelper.toHttpParams({
        id: 10,
        date: new Date(),
        states: [1, 3],
        child: {
          code: "111"
        }
      }).toString()
    ); //id=10&date=2019-08-02T13:19:09.014Z&states%5B0%5D=1&states%5B1%5D=3&child.code=111
    
  11. -1

    Esta soluciones de trabajo para mí,

    let params = new HttpParams();
    Object.keys(data).forEach(p => {
    params = params.append(p.toString(), data[p].toString());
    });

Dejar respuesta

Please enter your comment!
Please enter your name here