1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +00:00

account for pre-set value of an angular form before the options are set (#17872)

This commit is contained in:
Nick Krantz
2025-12-09 09:31:12 -06:00
committed by GitHub
parent bbf9157ec0
commit 456f02958a
2 changed files with 35 additions and 0 deletions

View File

@@ -451,6 +451,24 @@ describe("ChipSelectComponent", () => {
expect(disabledMenuItem?.disabled).toBe(true); expect(disabledMenuItem?.disabled).toBe(true);
}); });
it("should handle writeValue called before options are initialized", async () => {
const testApp = fixture.componentInstance;
component["rootTree"] = null;
component.writeValue("opt1");
expect(component["pendingValue"]).toBe("opt1");
expect(component["selectedOption"]).toBeUndefined();
testApp.options.set(testOptions);
fixture.detectChanges();
await fixture.whenStable();
expect(component["selectedOption"]?.value).toBe("opt1");
expect(component["pendingValue"]).toBeUndefined();
});
}); });
}); });

View File

@@ -100,10 +100,21 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor {
/** Tree constructed from `this.options` */ /** Tree constructed from `this.options` */
private rootTree?: ChipSelectOption<T> | null; private rootTree?: ChipSelectOption<T> | null;
/** Store the pending value when writeValue is called before options are initialized */
private pendingValue?: T;
constructor() { constructor() {
// Initialize the root tree whenever options change // Initialize the root tree whenever options change
effect(() => { effect(() => {
this.initializeRootTree(this.options()); this.initializeRootTree(this.options());
// If there's a pending value, apply it now that options are available
if (this.pendingValue !== undefined) {
this.selectedOption = this.findOption(this.rootTree, this.pendingValue);
this.setOrResetRenderedOptions();
this.pendingValue = undefined;
this.cdr.markForCheck();
}
}); });
// Focus the first menu item when menuItems change (e.g., navigating submenus) // Focus the first menu item when menuItems change (e.g., navigating submenus)
@@ -255,6 +266,12 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor {
/** Implemented as part of NG_VALUE_ACCESSOR */ /** Implemented as part of NG_VALUE_ACCESSOR */
writeValue(obj: T): void { writeValue(obj: T): void {
// If rootTree is not yet initialized, store the value to apply it later
if (!this.rootTree) {
this.pendingValue = obj;
return;
}
this.selectedOption = this.findOption(this.rootTree, obj); this.selectedOption = this.findOption(this.rootTree, obj);
this.setOrResetRenderedOptions(); this.setOrResetRenderedOptions();
// OnPush components require manual change detection when writeValue() is called // OnPush components require manual change detection when writeValue() is called