From 992cafc3955722e0b8ed59adcef2cd5fb0badf50 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Sat, 29 Oct 2022 09:53:06 +0200 Subject: [PATCH] fix(cdk/listbox): incorrectly validating preselected value (#25893) In #25856 the check that verifies the validity of the form control value was moved into `writeValue`. This works as expected for assignments after initialization, but it throws an error incorrectly if there is a preselected value, because `writeValue` will be called before the options are available. These changes resolve the issue by checking that the options have been initialized before throwing the error. (cherry picked from commit 166ed5efc97ab8823ec10bcb0c9f4c143305fc96) --- src/cdk/listbox/listbox.spec.ts | 36 +++++++++++++++++++++++++++++++++ src/cdk/listbox/listbox.ts | 31 ++++++++++++++++------------ 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/cdk/listbox/listbox.spec.ts b/src/cdk/listbox/listbox.spec.ts index 82f41e22b1f7..c9ac18836a01 100644 --- a/src/cdk/listbox/listbox.spec.ts +++ b/src/cdk/listbox/listbox.spec.ts @@ -883,6 +883,18 @@ describe('CdkOption and CdkListbox', () => { fixture.detectChanges(); }).toThrowError('Listbox has selected values that do not match any of its options.'); }); + + it('should not throw on init with a preselected form control and a dynamic set of options', () => { + expect(() => { + setupComponent(ListboxWithPreselectedFormControl, [ReactiveFormsModule]); + }).not.toThrow(); + }); + + it('should throw on init if the preselected value is invalid', () => { + expect(() => { + setupComponent(ListboxWithInvalidPreselectedFormControl, [ReactiveFormsModule]); + }).toThrowError('Listbox has selected values that do not match any of its options.'); + }); }); }); @@ -955,6 +967,30 @@ class ListboxWithFormControl { isActiveDescendant = false; } +@Component({ + template: ` +
+
{{option}}
+
+ `, +}) +class ListboxWithPreselectedFormControl { + options = ['a', 'b', 'c']; + formControl = new FormControl('c'); +} + +@Component({ + template: ` +
+
{{option}}
+
+ `, +}) +class ListboxWithInvalidPreselectedFormControl { + options = ['a', 'b', 'c']; + formControl = new FormControl('d'); +} + @Component({ template: `