Angular 4.3 – HttpClient set params

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

Por que isso não funciona? Apenas define o ‘aaa’ e NÃO o ‘bbb’

Além disso, eu tenho um object {aaa: 111, bbb: 222} Como posso definir todos os valores sem loop?

UPDATE (isso parece funcionar, mas como pode evitar o loop?)

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

Antes 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), eles adicionaram novo recurso (aceitar mapa de objects para headers e parâmetros HttpClient)

Indo adiante, o object pode ser passado diretamente em vez 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 destina-se a ser imutável. Os methods set e append não modificam a instância existente. Em vez disso, eles retornam novas instâncias, com as alterações aplicadas.

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

Essa abordagem funciona bem com o encadeamento de methods:

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

… embora isso possa ser estranho se você precisar envolver qualquer um deles em condições.

Seu loop funciona porque você está pegando uma referência para a nova instância retornada. O código que você postou não funciona, não funciona. Apenas chama set (), mas não pega o resultado.

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

Em versões mais recentes de @angular/common/http (5.0 e acima, pela aparência dele), você pode usar a chave HttpParamsOptions de HttpParamsOptions para passar o object diretamente em:

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

Isso apenas executa um loop forEach sob o capô , embora:

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

Quanto a mim, os methods de encadeamento são a maneira mais limpa

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

Outra opção para fazer isso é:

 this.httpClient.get('path', { params: Object.entries(data).reduce( (params, [key, value]) => params.set(key, value), new HttpParams()); }); 

Usando isso, você pode evitar o loop.

 // 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()); 

Além disso, sugiro fazer a function toHttpParams em seu serviço comumente usado. Então você pode chamar a function para converter o object para o 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()); } 

Atualizar:

Desde 5.0.0-beta.6 (2017-09-03), eles adicionaram novo recurso ( aceitar mapa de objects para headers e parâmetros HttpClient )

Indo adiante, o object pode ser passado diretamente em vez de HttpParams.

Esta é a outra razão, se você usou uma function comum como aHttpParams mencionada acima, pode facilmente removê-la ou fazer alterações, se necessário.

Tanto quanto eu posso ver a partir da implementação em https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts

Você deve fornecer valores separadamente – Você não pode evitar seu loop.

Há também um construtor que usa uma string como um parâmetro, mas está no formato param=value&param2=value2 portanto não há nenhum acordo para Você (em ambos os casos, você terminará com o loop de seu object).

Você sempre pode relatar uma solicitação de problema / recurso para angular, o que eu aconselho fortemente: https://github.com/angular/angular/issues

PS: Lembre-se da diferença entre os methods set e append 😉

2 alternativas fáceis

Sem objects HttpParams

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

Com objects HttpParams

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

Como o @MaciejTreder confirmou que temos que fazer um loop, aqui está um wrapper que opcionalmente permitirá adicionar um conjunto de parâmetros padrão:

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

Você pode usá-lo assim:

 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 

Como a class HTTP Params é imutável, você precisa encadear o método set:

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