mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 16:23:44 +00:00
account for pre-set value of an angular form before the options are set (#17872)
This commit is contained in:
@@ -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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user