mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
This reverts commit e3696ad0d6.
caused a test failure internally
PR Close #55293
This commit is contained in:
@@ -79,8 +79,6 @@ export const enum RuntimeErrorCode {
|
||||
// (undocumented)
|
||||
INVALID_SKIP_HYDRATION_HOST = -504,
|
||||
// (undocumented)
|
||||
LOOP_TRACK_DUPLICATE_KEYS = 955,
|
||||
// (undocumented)
|
||||
MISSING_DOCUMENT = 210,
|
||||
// (undocumented)
|
||||
MISSING_GENERATED_DEF = 906,
|
||||
|
||||
@@ -124,9 +124,6 @@ export const enum RuntimeErrorCode {
|
||||
// Output()
|
||||
OUTPUT_REF_DESTROYED = 953,
|
||||
|
||||
// Repeater errors
|
||||
LOOP_TRACK_DUPLICATE_KEYS = 955,
|
||||
|
||||
// Runtime dependency tracker errors
|
||||
RUNTIME_DEPS_INVALID_IMPORTED_TYPE = 1000,
|
||||
RUNTIME_DEPS_ORPHAN_COMPONENT = 1001,
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
import {setActiveConsumer} from '@angular/core/primitives/signals';
|
||||
|
||||
import {TrackByFunction} from '../../change_detection';
|
||||
import {formatRuntimeError, RuntimeErrorCode} from '../../errors';
|
||||
import {DehydratedContainerView} from '../../hydration/interfaces';
|
||||
import {findMatchingDehydratedView} from '../../hydration/views';
|
||||
import {assertDefined, assertFunction} from '../../util/assert';
|
||||
@@ -254,35 +253,6 @@ class LiveCollectionLContainerImpl extends
|
||||
}
|
||||
}
|
||||
|
||||
function detectDuplicateKeys(
|
||||
collection: Iterable<unknown>, trackByFn: TrackByFunction<unknown>): void {
|
||||
const keyToIdx = new Map<unknown, number>();
|
||||
let duplicatedKeysMsg: string[] = [];
|
||||
|
||||
let idx = 0;
|
||||
for (const item of collection) {
|
||||
const key = trackByFn(idx, item);
|
||||
|
||||
if (keyToIdx.has(key)) {
|
||||
const prevIdx = keyToIdx.get(key);
|
||||
duplicatedKeysMsg.push(`key "${key}" at index "${prevIdx}" and "${idx}"`);
|
||||
}
|
||||
|
||||
keyToIdx.set(key, idx++);
|
||||
}
|
||||
|
||||
if (duplicatedKeysMsg.length > 0) {
|
||||
const message = formatRuntimeError(
|
||||
RuntimeErrorCode.LOOP_TRACK_DUPLICATE_KEYS,
|
||||
'The provided track expression resulted in duplicated keys for a given collection. ' +
|
||||
'Adjust the tracking expression such that it uniquely identifies all the items in the collection. ' +
|
||||
'Duplicated keys were: \n' + duplicatedKeysMsg.join(', \n') + '.');
|
||||
|
||||
// tslint:disable-next-line:no-console
|
||||
console.warn(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The repeater instruction does update-time diffing of a provided collection (against the
|
||||
* 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
|
||||
metadata.liveCollection.reset();
|
||||
}
|
||||
|
||||
// make sure that tracking expression doesn't result in duplicate keys for a given collection
|
||||
if (ngDevMode && collection != null) {
|
||||
detectDuplicateKeys(collection, metadata.trackByFn);
|
||||
}
|
||||
|
||||
const liveCollection = metadata.liveCollection;
|
||||
reconcile(liveCollection, collection, metadata.trackByFn);
|
||||
|
||||
|
||||
@@ -273,32 +273,6 @@ describe('control flow - for', () => {
|
||||
fixture.detectChanges();
|
||||
expect(context).toBe(fixture.componentInstance);
|
||||
});
|
||||
|
||||
it('should warn about duplicated keys', () => {
|
||||
@Component({
|
||||
template: `@for (item of items; track item) {{{item}}}`,
|
||||
})
|
||||
class TestComponent {
|
||||
items = ['a', 'b', 'a', 'c', 'a'];
|
||||
}
|
||||
|
||||
spyOn(console, 'warn');
|
||||
|
||||
const fixture = TestBed.createComponent(TestComponent);
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement.textContent).toBe('abaca');
|
||||
expect(console.warn).toHaveBeenCalledTimes(2);
|
||||
expect(console.warn)
|
||||
.toHaveBeenCalledWith(jasmine.stringContaining(
|
||||
`NG0955: The provided track expression resulted in duplicated keys for a given collection.`));
|
||||
expect(console.warn)
|
||||
.toHaveBeenCalledWith(jasmine.stringContaining(
|
||||
`Adjust the tracking expression such that it uniquely identifies all the items in the collection. `));
|
||||
expect(console.warn)
|
||||
.toHaveBeenCalledWith(jasmine.stringContaining(`key "a" at index "0" and "2"`));
|
||||
expect(console.warn)
|
||||
.toHaveBeenCalledWith(jasmine.stringContaining(`key "a" at index "2" and "4"`));
|
||||
});
|
||||
});
|
||||
|
||||
describe('list diffing and view operations', () => {
|
||||
|
||||
Reference in New Issue
Block a user