Angular 4.3 - HttpClient set params

2019-01-08 09:26发布

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

Why this doesn't work? It only set the 'aaa' and NOT the 'bbb'

Also, I have an object { aaa: 111, bbb: 222 } How can I set all the values without looping?

UPDATE (this seems to work, but how can avoid the loop?)

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

10条回答
做自己的国王
2楼-- · 2019-01-08 09:33

Since HTTP Params class is immutable therefore you need to chain the set method:

const params = new HttpParams()
.set('aaa', '111')
.set('bbb', "222");
查看更多
唯我独甜
3楼-- · 2019-01-08 09:39

Before 5.0.0-beta.6

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

Since 5.0.0-beta.6

Since 5.0.0-beta.6 (2017-09-03) they added new feature (accept object map for HttpClient headers & params)

Going forward the object can be passed directly instead of 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})
}
查看更多
手持菜刀,她持情操
4楼-- · 2019-01-08 09:40

Using this you can avoid the 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());

Furthermore, I suggest making toHttpParams function in your commonly used service. So you can call the function to convert the object to the 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());
}

Update:

Since 5.0.0-beta.6 (2017-09-03) they added new feature (accept object map for HttpClient headers & params)

Going forward the object can be passed directly instead of HttpParams.

This is the other reason if you have used one common function like toHttpParams mentioned above, you can easily remove it or do changes if required.

查看更多
Anthone
5楼-- · 2019-01-08 09:41

As far as I can see from the implementation at https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts

You must provide values separately - You are not able to avoid your loop.

There is also a constructor which takes a string as a parameter, but it is in form param=value&param2=value2 so there is no deal for You (in both cases you will finish with looping your object).

You can always report an issue/feature request to angular, what I strongly advise: https://github.com/angular/angular/issues

PS: Remember about difference between set and append methods ;)

查看更多
再贱就再见
6楼-- · 2019-01-08 09:48

2 Easy Alternatives

Without HttpParams Objects

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

With HttpParams Objects

let body = new HttpParams({
  fromObject : {
    'email' : emailId,
    'password' : password
  }
}
this.http.post(url,body);
查看更多
疯言疯语
7楼-- · 2019-01-08 09:55

Since @MaciejTreder confirmed that we have to loop, here's a wrapper that will optionally let you add to a set of default params:

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

You can use it like so:

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
查看更多
登录 后发表回答