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,
})