diff --git a/adev/src/content/api-examples/common/pipes/ts/keyvalue_pipe.ts b/adev/src/content/api-examples/common/pipes/ts/keyvalue_pipe.ts index 0f1f4f4477e..05d45f1345f 100644 --- a/adev/src/content/api-examples/common/pipes/ts/keyvalue_pipe.ts +++ b/adev/src/content/api-examples/common/pipes/ts/keyvalue_pipe.ts @@ -17,6 +17,8 @@ import {Component} from '@angular/core';
{{ item.key }}:{{ item.value }}

Map

{{ item.key }}:{{ item.value }}
+

Natural order

+
{{ item.key }}:{{ item.value }}
`, standalone: false, diff --git a/goldens/public-api/common/index.api.md b/goldens/public-api/common/index.api.md index f2375763302..cb7e4fb8b9b 100644 --- a/goldens/public-api/common/index.api.md +++ b/goldens/public-api/common/index.api.md @@ -367,19 +367,19 @@ export interface KeyValue { export class KeyValuePipe implements PipeTransform { constructor(differs: KeyValueDiffers); // (undocumented) - transform(input: ReadonlyMap, compareFn?: (a: KeyValue, b: KeyValue) => number): Array>; + transform(input: ReadonlyMap, compareFn?: ((a: KeyValue, b: KeyValue) => number) | null): Array>; // (undocumented) - transform(input: Record, compareFn?: (a: KeyValue, b: KeyValue) => number): Array>; + transform(input: Record, compareFn?: ((a: KeyValue, b: KeyValue) => number) | null): Array>; // (undocumented) - transform(input: Record | ReadonlyMap, compareFn?: (a: KeyValue, b: KeyValue) => number): Array>; + transform(input: Record | ReadonlyMap, compareFn?: ((a: KeyValue, b: KeyValue) => number) | null): Array>; // (undocumented) - transform(input: null | undefined, compareFn?: (a: KeyValue, b: KeyValue) => number): null; + transform(input: null | undefined, compareFn?: ((a: KeyValue, b: KeyValue) => number) | null): null; // (undocumented) - transform(input: ReadonlyMap | null | undefined, compareFn?: (a: KeyValue, b: KeyValue) => number): Array> | null; + transform(input: ReadonlyMap | null | undefined, compareFn?: ((a: KeyValue, b: KeyValue) => number) | null): Array> | null; // (undocumented) - transform(input: Record | null | undefined, compareFn?: (a: KeyValue, b: KeyValue) => number): Array> | null; + transform(input: Record | null | undefined, compareFn?: ((a: KeyValue, b: KeyValue) => number) | null): Array> | null; // (undocumented) - transform(input: Record | ReadonlyMap | null | undefined, compareFn?: (a: KeyValue, b: KeyValue) => number): Array> | null; + transform(input: Record | ReadonlyMap | null | undefined, compareFn?: ((a: KeyValue, b: KeyValue) => number) | null): Array> | null; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; // (undocumented) diff --git a/packages/common/src/pipes/keyvalue_pipe.ts b/packages/common/src/pipes/keyvalue_pipe.ts index dd09098da2d..10bb50998b0 100644 --- a/packages/common/src/pipes/keyvalue_pipe.ts +++ b/packages/common/src/pipes/keyvalue_pipe.ts @@ -39,6 +39,7 @@ export interface KeyValue { * The output array will be ordered by keys. * By default the comparator will be by Unicode point value. * You can optionally pass a compareFn if your keys are complex types. + * Passing `null` as the compareFn will use natural ordering of the input. * * @usageNotes * ### Examples @@ -60,7 +61,8 @@ export class KeyValuePipe implements PipeTransform { private differ!: KeyValueDiffer; private keyValues: Array> = []; - private compareFn: (a: KeyValue, b: KeyValue) => number = defaultComparator; + private compareFn: ((a: KeyValue, b: KeyValue) => number) | null = + defaultComparator; /* * NOTE: when the `input` value is a simple Record object, the keys are extracted with @@ -69,35 +71,35 @@ export class KeyValuePipe implements PipeTransform { */ transform( input: ReadonlyMap, - compareFn?: (a: KeyValue, b: KeyValue) => number, + compareFn?: ((a: KeyValue, b: KeyValue) => number) | null, ): Array>; transform( input: Record, - compareFn?: (a: KeyValue, b: KeyValue) => number, + compareFn?: ((a: KeyValue, b: KeyValue) => number) | null, ): Array>; transform( input: Record | ReadonlyMap, - compareFn?: (a: KeyValue, b: KeyValue) => number, + compareFn?: ((a: KeyValue, b: KeyValue) => number) | null, ): Array>; transform( input: null | undefined, - compareFn?: (a: KeyValue, b: KeyValue) => number, + compareFn?: ((a: KeyValue, b: KeyValue) => number) | null, ): null; transform( input: ReadonlyMap | null | undefined, - compareFn?: (a: KeyValue, b: KeyValue) => number, + compareFn?: ((a: KeyValue, b: KeyValue) => number) | null, ): Array> | null; transform( input: Record | null | undefined, - compareFn?: (a: KeyValue, b: KeyValue) => number, + compareFn?: ((a: KeyValue, b: KeyValue) => number) | null, ): Array> | null; transform( input: Record | ReadonlyMap | null | undefined, - compareFn?: (a: KeyValue, b: KeyValue) => number, + compareFn?: ((a: KeyValue, b: KeyValue) => number) | null, ): Array> | null; transform( input: undefined | null | {[key: string]: V; [key: number]: V} | ReadonlyMap, - compareFn: (a: KeyValue, b: KeyValue) => number = defaultComparator, + compareFn: ((a: KeyValue, b: KeyValue) => number) | null = defaultComparator, ): Array> | null { if (!input || (!(input instanceof Map) && typeof input !== 'object')) { return null; @@ -116,7 +118,9 @@ export class KeyValuePipe implements PipeTransform { }); } if (differChanges || compareFnChanged) { - this.keyValues.sort(compareFn); + if (compareFn) { + this.keyValues.sort(compareFn); + } this.compareFn = compareFn; } return this.keyValues; diff --git a/packages/common/test/pipes/keyvalue_pipe_spec.ts b/packages/common/test/pipes/keyvalue_pipe_spec.ts index dedb05a5e3b..39e31517e86 100644 --- a/packages/common/test/pipes/keyvalue_pipe_spec.ts +++ b/packages/common/test/pipes/keyvalue_pipe_spec.ts @@ -61,6 +61,13 @@ describe('KeyValuePipe', () => { {key: 'b', value: 1}, ]); }); + it('should not order by alpha when compareFn is null', () => { + const pipe = new KeyValuePipe(defaultKeyValueDiffers); + expect(pipe.transform({'b': 1, 'a': 1}, null)).toEqual([ + {key: 'b', value: 1}, + {key: 'a', value: 1}, + ]); + }); it('should reorder when compareFn changes', () => { const pipe = new KeyValuePipe(defaultKeyValueDiffers); const input = {'b': 1, 'a': 2}; @@ -163,6 +170,21 @@ describe('KeyValuePipe', () => { {key: {id: 1}, value: 1}, ]); }); + it('should not order by alpha when compareFn is null', () => { + const pipe = new KeyValuePipe(defaultKeyValueDiffers); + expect( + pipe.transform( + new Map([ + ['b', 1], + ['a', 1], + ]), + null, + ), + ).toEqual([ + {key: 'b', value: 1}, + {key: 'a', value: 1}, + ]); + }); it('should reorder when compareFn changes', () => { const pipe = new KeyValuePipe(defaultKeyValueDiffers); const input = new Map([ diff --git a/packages/examples/common/pipes/ts/keyvalue_pipe.ts b/packages/examples/common/pipes/ts/keyvalue_pipe.ts index be258d090de..0069515b3c8 100644 --- a/packages/examples/common/pipes/ts/keyvalue_pipe.ts +++ b/packages/examples/common/pipes/ts/keyvalue_pipe.ts @@ -16,6 +16,8 @@ import {Component} from '@angular/core';
{{ item.key }}:{{ item.value }}

Map

{{ item.key }}:{{ item.value }}
+

Natural order

+
{{ item.key }}:{{ item.value }}
`, standalone: false, })