Skip to content

Commit 19a238d

Browse files
committed
Revert "refactor(core): warn about duplicated keys when using built-in @for (angular#55243)" (angular#55293)
This reverts commit e3696ad. caused a test failure internally PR Close angular#55293
1 parent 92debf4 commit 19a238d

File tree

4 files changed

+0
-66
lines changed

4 files changed

+0
-66
lines changed

goldens/public-api/core/errors.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ export const enum RuntimeErrorCode {
7979
// (undocumented)
8080
INVALID_SKIP_HYDRATION_HOST = -504,
8181
// (undocumented)
82-
LOOP_TRACK_DUPLICATE_KEYS = 955,
83-
// (undocumented)
8482
MISSING_DOCUMENT = 210,
8583
// (undocumented)
8684
MISSING_GENERATED_DEF = 906,

packages/core/src/errors.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,6 @@ export const enum RuntimeErrorCode {
124124
// Output()
125125
OUTPUT_REF_DESTROYED = 953,
126126

127-
// Repeater errors
128-
LOOP_TRACK_DUPLICATE_KEYS = 955,
129-
130127
// Runtime dependency tracker errors
131128
RUNTIME_DEPS_INVALID_IMPORTED_TYPE = 1000,
132129
RUNTIME_DEPS_ORPHAN_COMPONENT = 1001,

packages/core/src/render3/instructions/control_flow.ts

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import {setActiveConsumer} from '@angular/core/primitives/signals';
1010

1111
import {TrackByFunction} from '../../change_detection';
12-
import {formatRuntimeError, RuntimeErrorCode} from '../../errors';
1312
import {DehydratedContainerView} from '../../hydration/interfaces';
1413
import {findMatchingDehydratedView} from '../../hydration/views';
1514
import {assertDefined, assertFunction} from '../../util/assert';
@@ -254,35 +253,6 @@ class LiveCollectionLContainerImpl extends
254253
}
255254
}
256255

257-
function detectDuplicateKeys(
258-
collection: Iterable<unknown>, trackByFn: TrackByFunction<unknown>): void {
259-
const keyToIdx = new Map<unknown, number>();
260-
let duplicatedKeysMsg: string[] = [];
261-
262-
let idx = 0;
263-
for (const item of collection) {
264-
const key = trackByFn(idx, item);
265-
266-
if (keyToIdx.has(key)) {
267-
const prevIdx = keyToIdx.get(key);
268-
duplicatedKeysMsg.push(`key "${key}" at index "${prevIdx}" and "${idx}"`);
269-
}
270-
271-
keyToIdx.set(key, idx++);
272-
}
273-
274-
if (duplicatedKeysMsg.length > 0) {
275-
const message = formatRuntimeError(
276-
RuntimeErrorCode.LOOP_TRACK_DUPLICATE_KEYS,
277-
'The provided track expression resulted in duplicated keys for a given collection. ' +
278-
'Adjust the tracking expression such that it uniquely identifies all the items in the collection. ' +
279-
'Duplicated keys were: \n' + duplicatedKeysMsg.join(', \n') + '.');
280-
281-
// tslint:disable-next-line:no-console
282-
console.warn(message);
283-
}
284-
}
285-
286256
/**
287257
* The repeater instruction does update-time diffing of a provided collection (against the
288258
* collection seen previously) and maps changes in the collection to views structure (by adding,
@@ -308,11 +278,6 @@ export function ɵɵrepeater(collection: Iterable<unknown>|undefined|null): void
308278
metadata.liveCollection.reset();
309279
}
310280

311-
// make sure that tracking expression doesn't result in duplicate keys for a given collection
312-
if (ngDevMode && collection != null) {
313-
detectDuplicateKeys(collection, metadata.trackByFn);
314-
}
315-
316281
const liveCollection = metadata.liveCollection;
317282
reconcile(liveCollection, collection, metadata.trackByFn);
318283

packages/core/test/acceptance/control_flow_for_spec.ts

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -273,32 +273,6 @@ describe('control flow - for', () => {
273273
fixture.detectChanges();
274274
expect(context).toBe(fixture.componentInstance);
275275
});
276-
277-
it('should warn about duplicated keys', () => {
278-
@Component({
279-
template: `@for (item of items; track item) {{{item}}}`,
280-
})
281-
class TestComponent {
282-
items = ['a', 'b', 'a', 'c', 'a'];
283-
}
284-
285-
spyOn(console, 'warn');
286-
287-
const fixture = TestBed.createComponent(TestComponent);
288-
fixture.detectChanges();
289-
expect(fixture.nativeElement.textContent).toBe('abaca');
290-
expect(console.warn).toHaveBeenCalledTimes(2);
291-
expect(console.warn)
292-
.toHaveBeenCalledWith(jasmine.stringContaining(
293-
`NG0955: The provided track expression resulted in duplicated keys for a given collection.`));
294-
expect(console.warn)
295-
.toHaveBeenCalledWith(jasmine.stringContaining(
296-
`Adjust the tracking expression such that it uniquely identifies all the items in the collection. `));
297-
expect(console.warn)
298-
.toHaveBeenCalledWith(jasmine.stringContaining(`key "a" at index "0" and "2"`));
299-
expect(console.warn)
300-
.toHaveBeenCalledWith(jasmine.stringContaining(`key "a" at index "2" and "4"`));
301-
});
302276
});
303277

304278
describe('list diffing and view operations', () => {

0 commit comments

Comments
 (0)