httpparams angular 5 example
Angular 4.3-HttpClient establece parĂ¡metros (12)
let httpParams = new HttpParams().set(''aaa'', ''111'');
httpParams.set(''bbb'', ''222'');
¿Por qué esto no funciona? Solo establece el ''aaa'' y NO el ''bbb''
Además, tengo un objeto {aaa: 111, bbb: 222} ¿Cómo puedo establecer todos los valores sin bucle?
ACTUALIZACIÓN (esto parece funcionar, pero ¿cómo puede evitar el bucle?)
let httpParams = new HttpParams();
Object.keys(data).forEach(function (key) {
httpParams = httpParams.append(key, data[key]);
});
Par de alternativas fáciles
Sin usar objetos
HttpParams
let body = {
params : {
''email'' : emailId,
''password'' : password
}
}
this.http.post(url, body);
Usar objetos
HttpParams
let body = new HttpParams({
fromObject : {
''email'' : emailId,
''password'' : password
}
})
this.http.post(url, body);
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) agregaron una nueva función (aceptar mapa de objetos para encabezados y parámetros HttpClient)
En el futuro, el objeto se puede pasar 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})
}
Dado que @MaciejTreder confirmó que tenemos que hacer un bucle, aquí hay un contenedor que opcionalmente le permitirá agregar a un conjunto de parámetros predeterminados:
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 };
}
Puedes usarlo 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
Dado que la clase HTTP Params es inmutable, por lo tanto, debe encadenar el método set:
const params = new HttpParams()
.set(''aaa'', ''111'')
.set(''bbb'', "222");
En cuanto a mí, encadenar métodos
set
es la forma más limpia
const params = new HttpParams()
.set(''aaa'', ''111'')
.set(''bbb'', "222");
En versiones más recientes de
@angular/common/http
(5.0 y superior, por lo que parece), puede usar la tecla
HttpParamsOptions
de
HttpParamsOptions
para pasar el objeto directamente:
let httpParams = new HttpParams({ fromObject: { aaa: 111, bbb: 222 } });
Sin embargo, esto solo ejecuta un bucle
forEach
debajo del capó
:
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]);
});
Estas soluciones funcionan para mí,
let params = new HttpParams(); Object.keys(data).forEach(p => { params = params.append(p.toString(), data[p].toString()); });
HttpParams está destinado a ser inmutable.
Los métodos
set
y
append
no modifican la instancia existente.
En su lugar, devuelven nuevas instancias, 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'');
... aunque eso podría ser incómodo si necesita envolver alguno de ellos en condiciones.
Su ciclo funciona porque está tomando una referencia a la nueva instancia devuelta. El código que publicaste que no funciona, no funciona. Simplemente llama a set () pero no toma el resultado.
let httpParams = new HttpParams().set(''aaa'', ''111''); // now it has aaa
httpParams.set(''bbb'', ''222''); // result has both but is discarded
Mi clase auxiliar (ts) para convertir cualquier objeto dto complejo (no solo "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
Otra opción para hacerlo es:
this.httpClient.get(''path'', {
params: Object.entries(data).reduce(
(params, [key, value]) => params.set(key, value), new HttpParams());
});
Por lo que puedo ver de la implementación en https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts
Debe proporcionar valores por separado: no puede evitar su ciclo.
También hay un constructor que toma una cadena como parámetro, pero tiene la forma
param=value¶m2=value2
por lo que no hay trato para usted (en ambos casos terminará con el bucle de su objeto).
Siempre puede informar una solicitud de problema / función a angular, lo que le recomiendo encarecidamente: https://github.com/angular/angular/issues
PD: recuerde la diferencia entre los métodos
set
y
append
;)
Usando esto puedes 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 que toHttpParams funcione en su servicio de uso común. Entonces puede llamar a la función para convertir el objeto en 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());
}
Actualizar:
Desde 5.0.0-beta.6 (2017-09-03) agregaron una nueva función ( aceptar mapa de objetos para encabezados y parámetros HttpClient )
En el futuro, el objeto se puede pasar directamente en lugar de HttpParams.
Esta es la otra razón si ha utilizado una función común como toHttpParams mencionada anteriormente, puede eliminarla fácilmente o hacer cambios si es necesario.