let httpParams = new HttpParams().set('aaa', '111');
httpParams.set('bbb', '222');
Pourquoi ça ne marche pas? Il ne définit que le 'aaa' et PAS le 'bbb'
De plus, j'ai un objet {aaa: 111, bbb: 222} Comment puis-je définir toutes les valeurs sans boucle?
UPDATE (cela semble fonctionner, mais comment éviter la boucle?)
let httpParams = new HttpParams();
Object.keys(data).forEach(function (key) {
httpParams = httpParams.append(key, data[key]);
});
let httpParams = new HttpParams();
Object.keys(data).forEach(function (key) {
httpParams = httpParams.append(key, data[key]);
});
Depuis la version 5.0.0-beta.6 (2017-09-03), ils ont ajouté une nouvelle fonctionnalité (accepte la mappe d'objets pour les en-têtes et paramètres HttpClient).
À l'avenir, l'objet peut être passé directement à la place 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})
}
HttpParams se veut immuable. Les méthodes set
et append
ne modifient pas l'instance existante. Au lieu de cela, ils renvoient de nouvelles instances, avec les modifications appliquées.
let params = new HttpParams().set('aaa', 'A'); // now it has aaa
params = params.set('bbb', 'B'); // now it has both
Cette approche fonctionne bien avec la méthode de chaînage:
const params = new HttpParams()
.set('one', '1')
.set('two', '2');
... bien que cela puisse être gênant si vous devez en emballer un dans des conditions.
Votre boucle fonctionne parce que vous récupérez une référence à la nouvelle instance renvoyée. Le code que vous avez posté qui ne fonctionne pas ne fonctionne pas. Il appelle simplement set () mais ne récupère pas le résultat.
let httpParams = new HttpParams().set('aaa', '111'); // now it has aaa
httpParams.set('bbb', '222'); // result has both but is discarded
Dans les versions plus récentes de @angular/common/http
(versions 5.0 et supérieures, par son apparence), vous pouvez utiliser la clé fromObject
de HttpParamsOptions
pour passer l'objet directement dans:
let httpParams = new HttpParams({ fromObject: { aaa: 111, bbb: 222 } });
Cela lance juste une boucle forEach
sous le capot , bien 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]);
});
Pour moi, enchaîner set
méthodes est le moyen le plus propre
const params = new HttpParams()
.set('aaa', '111')
.set('bbb', "222");
HttpParams
let body = {
params : {
'email' : emailId,
'password' : password
}
}
this.http.post(url, body);
HttpParams
Objetslet body = new HttpParams({
fromObject : {
'email' : emailId,
'password' : password
}
})
this.http.post(url, body);
Une autre option est la suivante:
this.httpClient.get('path', {
params: Object.entries(data).reduce(
(params, [key, value]) => params.set(key, value), new HttpParams());
});
Comme la classe HTTP Params est immuable, vous devez donc chaîner la méthode set:
const params = new HttpParams()
.set('aaa', '111')
.set('bbb', "222");
En utilisant cela, vous pouvez éviter la boucle.
// 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());
De plus, je suggère de faire toHttpParams une fonction dans votre service couramment utilisé. Vous pouvez donc appeler la fonction pour convertir l'objet 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());
}
Mise à jour:
Depuis la version 5.0.0-beta.6 (2017-09-03), ils ont ajouté une nouvelle fonctionnalité ( accepte la carte des objets pour les en-têtes et les paramètres HttpClient )
À l'avenir, l'objet peut être passé directement à la place de HttpParams.
C’est l’autre raison si vous avez utilisé une fonction commune telle que toHttpParams mentionnée ci-dessus, vous pouvez facilement la supprimer ou effectuer des modifications si nécessaire.
Pour autant que je puisse voir de la mise en œuvre à https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts
Vous devez fournir des valeurs séparément - Vous ne pouvez pas éviter votre boucle.
Il existe également un constructeur qui prend une chaîne en tant que paramètre, mais sous la forme param=value¶m2=value2
, il n'y a donc pas d'accord pour vous (dans les deux cas, vous finirez par boucler votre objet).
Vous pouvez toujours signaler un problème/demande de fonctionnalité à angular, ce que je conseille vivement: https://github.com/angular/angular/issues
PS: Rappelez-vous de la différence entre les méthodes set
et append
;)
Puisque @MaciejTreder a confirmé la nécessité de la boucle, voici un wrapper qui vous permettra éventuellement d’ajouter à un ensemble de paramètres par défaut:
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 };
}
Vous pouvez l'utiliser comme ceci:
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
Ma classe d'assistance (ts) pour convertir n'importe quel objet dto complexe (pas seulement "dictionnaire de chaînes") en 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