let httpParams = new HttpParams().set('aaa', '111'); httpParams.set('bbb', '222');
Pourquoi cela ne fonctionne pas? Il ne définit que le ‘aaa’ et non le ‘bbb’
En outre, j’ai un object {aaa: 111, bbb: 222} Comment puis-je définir toutes les valeurs sans boucler?
MISE À JOUR (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é (acceptation de la carte object pour les en-têtes et parameters HttpClient)
En allant de l’avant, l’object peut être passé directement au lieu de HttpParams.
getCounsortinges(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/counsortinges", {params: data}) }
HttpParams est destiné à être 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 le chaînage des méthodes:
const params = new HttpParams() .set('one', '1') .set('two', '2');
… bien que cela puisse être gênant si vous devez en envelopper un dans des conditions.
Votre boucle fonctionne parce que vous saisissez une référence à la nouvelle instance renvoyée. Le code que vous avez posté ne fonctionne pas, pas. Il appelle simplement set () mais ne saisit 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
(5.0 et supérieures, à première vue), vous pouvez utiliser la clé HttpParamsOptions
de HttpParamsOptions
pour passer l’object directement dans:
let httpParams = new HttpParams({ fromObject: { aaa: 111, bbb: 222 } });
Cela ne fait que forEach
une boucle forEach
sous le capot :
this.map = new Map(); Object.keys(options.fromObject).forEach(key => { const value = (options.fromObject as any)[key]; this.map !.set(key, Array.isArray(value) ? value : [value]); });
Pour ma part, enchaîner les méthodes de set
est la méthode la plus propre
const params = new HttpParams() .set('aaa', '111') .set('bbb', "222");
Une autre option pour le faire est:
this.httpClient.get('path', { params: Object.ensortinges(data).reduce( (params, [key, value]) => params.set(key, value), new HttpParams()); });
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());
En outre, je suggère de faire fonctionner toHttpParams dans votre service couramment utilisé. Vous pouvez donc appeler la fonction pour convertir l’object 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()); }
Mettre à jour:
Depuis la version 5.0.0-beta.6 (2017-09-03), ils ont ajouté une nouvelle fonctionnalité ( acceptation de la carte object pour les en-têtes et parameters HttpClient )
En allant de l’avant, l’object peut être passé directement au lieu de HttpParams.
Ceci est l’autre raison si vous avez utilisé une fonction commune telle que toHttpParams mentionnée ci-dessus, vous pouvez facilement la supprimer ou apporter des modifications si nécessaire.
Pour autant que je puisse voir de l’implémentation à 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 y a aussi un constructeur qui prend une chaîne comme paramètre, mais il est dans la forme param=value¶m2=value2
donc il n’y a pas de deal pour vous (dans les deux cas vous finirez par boucler votre object).
Vous pouvez toujours signaler une demande de problème / fonctionnalité à angular, ce que je conseille fortement: https://github.com/angular/angular/issues
PS: Rappelez-vous de la différence entre les méthodes set
et append
😉
2 alternatives faciles
Sans objects HttpParams
let body = { params : { 'email' : emailId, 'password' : password } } this.http.post(url,body);
Avec des objects HttpParams
let body = new HttpParams({ fromObject : { 'email' : emailId, 'password' : password } } this.http.post(url,body);
Puisque @MaciejTreder a confirmé que nous devions boucler, voici un wrapper qui vous laissera éventuellement append un ensemble de parameters 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 === 'ssortingng') ? (v.length > 0) : (v !== null && v !== undefined); }) .forEach(key => { httpParams = httpParams.set(key, params[key]); }); return { params: httpParams }; }
Vous pouvez l’utiliser comme ça:
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
Puisque la classe HTTP Params est immuable, vous devez enchaîner la méthode set:
const params = new HttpParams() .set('aaa', '111') .set('bbb', "222");