From 575a2d162c2caccb645d6f0b3cd52959b7d4f00c Mon Sep 17 00:00:00 2001 From: Harun Urhan Date: Sun, 6 Dec 2020 18:19:58 +0100 Subject: [PATCH] feat(common): implement `appendAll()` method on `HttpParams` (#20930) Adds an `appendAll()` method to `HttpParams` that can construct the HTTP request/response body from an object of parameters and values. This avoids calling `append()` multiple times when multiple parameters need to be added. Fixes #20798 PR Close #20930 --- goldens/public-api/common/http/http.d.ts | 3 +++ packages/common/http/src/params.ts | 24 ++++++++++++++++++++++-- packages/common/http/test/params_spec.ts | 6 ++++++ 3 files changed, 31 insertions(+), 2 deletions(-) mode change 100755 => 100644 packages/common/http/src/params.ts diff --git a/goldens/public-api/common/http/http.d.ts b/goldens/public-api/common/http/http.d.ts index 0d79d7073b..5dfb3aeee7 100644 --- a/goldens/public-api/common/http/http.d.ts +++ b/goldens/public-api/common/http/http.d.ts @@ -1570,6 +1570,9 @@ export declare interface HttpParameterCodec { export declare class HttpParams { constructor(options?: HttpParamsOptions); append(param: string, value: string): HttpParams; + appendAll(params: { + [param: string]: string | string[]; + }): HttpParams; delete(param: string, value?: string): HttpParams; get(param: string): string | null; getAll(param: string): string[] | null; diff --git a/packages/common/http/src/params.ts b/packages/common/http/src/params.ts old mode 100755 new mode 100644 index 7e58f8d4cf..87cdedd61c --- a/packages/common/http/src/params.ts +++ b/packages/common/http/src/params.ts @@ -209,6 +209,26 @@ export class HttpParams { return this.clone({param, value, op: 'a'}); } + /** + * Constructs a new body with appended values for the given parameter name. + * @param params parameters and values + * @return A new body with the new value. + */ + appendAll(params: {[param: string]: string|string[]}): HttpParams { + const updates: Update[] = []; + Object.keys(params).forEach(param => { + const value = params[param]; + if (Array.isArray(value)) { + value.forEach(_value => { + updates.push({param, value: _value, op: 'a'}); + }); + } else { + updates.push({param, value, op: 'a'}); + } + }); + return this.clone(updates); + } + /** * Replaces the value for a parameter. * @param param The parameter name. @@ -251,10 +271,10 @@ export class HttpParams { .join('&'); } - private clone(update: Update): HttpParams { + private clone(update: Update|Update[]): HttpParams { const clone = new HttpParams({encoder: this.encoder} as HttpParamsOptions); clone.cloneFrom = this.cloneFrom || this; - clone.updates = (this.updates || []).concat([update]); + clone.updates = (this.updates || []).concat(update); return clone; } diff --git a/packages/common/http/test/params_spec.ts b/packages/common/http/test/params_spec.ts index a4a8b9c581..9cd8422624 100644 --- a/packages/common/http/test/params_spec.ts +++ b/packages/common/http/test/params_spec.ts @@ -36,6 +36,12 @@ import {HttpParams} from '@angular/common/http/src/params'; expect(mutated.toString()).toEqual('a=b&a=c'); }); + it('should allow appending all parameters', () => { + const body = new HttpParams({fromString: 'a=a1&b=b1'}); + const mutated = body.appendAll({a: ['a2', 'a3'], b: 'b2'}); + expect(mutated.toString()).toEqual('a=a1&a=a2&a=a3&b=b1&b=b2'); + }); + it('should allow deletion of parameters', () => { const body = new HttpParams({fromString: 'a=b&c=d&e=f'}); const mutated = body.delete('c');