Angular 4.3 - HttpClient设置参数

时间:2017-07-20 09:16:16

标签: angular angular-http

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

为什么这不起作用? 它只设置了'aaa'而不是' bbb'

另外,我有一个对象{aaa:111,bbb:222} 如何在不循环的情况下设置所有值?

UPDATE(这似乎有效,但如何避免循环?)

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

14 个答案:

答案 0 :(得分:64)

在5.0.0-beta.6之前

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

自5.0.0-beta.6

  

自5.0.0-beta.6(2017-09-03)以来,他们添加了新功能(接受HttpClient标头和参数的对象映射)

     

可以直接传递对象而不是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})
}

答案 1 :(得分:60)

HttpParams旨在不可变。 String lines=""; while((line = bufferedReader.readLine()) !=null ){ lines = lines + line; } String[] splitLines = lines.split("\\s+"); for (String words: splitLines) { System.out.println(words); } set方法无法修改现有实例。相反,它们会返回新实例,并应用更改。

append

这种方法适用于方法链:

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

......如果你需要在条件中包装其中任何一个,那可能会很尴尬。

你的循环有效,因为你正在抓取对返回的新实例的引用。您发布的代码不起作用,但没有。它只是调用set()但不会获取结果。

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

答案 2 :(得分:32)

@angular/common/http的更新版本中(5.0及更高版本,通过它的外观),您可以使用HttpParamsOptionsfromObject键直接传递对象:

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

这只会运行forEach循环under the hood,但是:

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

答案 3 :(得分:18)

至于我,链接mlp = nn.Sequential() c = nn.Parallel(1,2) for i = 1, 10 do c:add(t:clone('weight', 'bias')) end mlp:add(c) 方法是最干净的方法

set

答案 4 :(得分:9)

2个简单的选择

  

没有HttpParams对象

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

带有HttpParams对象

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

答案 5 :(得分:8)

另一个选择是:

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

答案 6 :(得分:6)

由于HTTP Params类是不可变的,因此您需要链接 设定方法:

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

答案 7 :(得分:5)

使用它可以避免循环。

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

此外,我建议您在常用服务中使用 toHttpParams 功能。因此,您可以调用该函数将对象转换为 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());
}

更新:

  

自5.0.0-beta.6(2017-09-03)以来,他们添加了新功能(accept object map for HttpClient headers & params

     

可以直接传递对象而不是HttpParams。

这是另一个原因,如果您使用了上面提到的 toHttpParams 之类的常用功能,您可以轻松删除它或根据需要进行更改。

答案 8 :(得分:2)

据我在https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts

的实施情况所见

您必须单独提供值 - 您无法避免循环。

还有一个构造函数,它将一个字符串作为参数,但它的格式为param=value&param2=value2,因此没有任何交易(在这两种情况下,您将完成循环对象)。

您始终可以向角度报告问题/功能请求,我强烈建议: https://github.com/angular/angular/issues

PS:请记住setappend方法之间的区别;)

答案 9 :(得分:2)

appendAll 函数

import { HttpParams } from "@angular/common/http";

export class BuildUrl {

    /**
     * append all params
     * @param args {unknown[]}
     * @returns {HttpParams}
     */
    static appendAll(...args: unknown[]): HttpParams {
        let params = new HttpParams();
        args.forEach(param => {
            Object.keys(param).forEach((key) => {
                params = params.append(key, param[key]);
            });
        });
        return params;
    }
}

我们如何在服务中使用它。

getData( pag: PaginationRequest, description: string = ''): Observable<any> {
    const params = BuildUrl.appendAll(pag,
      { description },
    );
    return this.http.get(url, { params });
  }

答案 10 :(得分:1)

由于@MaciejTreder确认我们必须循环,这里有一个包装器,可以选择添加一组默认参数:

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

您可以像这样使用它:

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

答案 11 :(得分:1)

我的助手类(ts)将任何复杂的dto对象(不仅是“字符串字典”)转换为HttpParams:

var viewModels = _clientRepository
                    .SearchPortfolios(c => true, includeClients: true)
                    .Select(c => new ViewModels.Portfolio()
                    {
                        Name = c.Name,
                        Id = c.Id,
                        ClientName = c.Client.Name // Null Reference Exception
                    }).ToList();

答案 12 :(得分:1)

只需添加一下,即可添加多个具有相同键名的参数,例如: www.test.com/home?id=1&id=2

let params = new HttpParams();
params = params.append(key, value);

使用append,如果使用set,它将使用相同的键名覆盖以前的值。

答案 13 :(得分:-1)

此解决方案对我有用,

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