Skip to content

Fix "None of the above" option selection - #1666

Closed
sofyakurilova wants to merge 1 commit into
dev_oldfrom
bug/none_selection
Closed

sofyakurilova wants to merge 1 commit into
dev_oldfrom
bug/none_selection

Conversation

@sofyakurilova

Copy link
Copy Markdown
Collaborator

No description provided.

@sofyakurilova
sofyakurilova requested a review from hitnik October 15, 2026 13:31
@sofyakurilova sofyakurilova self-assigned this Oct 15, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the 'None of the above' selection logic in DynamicFormComponent to subscribe to individual option changes instead of the entire form group's value changes, simplifying the logic and removing the need for startWith and pairwise RxJS operators. It also adds comprehensive unit tests to verify this behavior. The review feedback suggests optimizing the selection logic by caching control lookups and avoiding redundant setValue calls. Additionally, it recommends adding a type check in getNoneOptionIndex to ensure the option value is a string before calling toLowerCase(), preventing potential runtime errors.

Comment on lines +225 to 246
private applyNoneLogic(control: FormGroup, noneKey: string) {
Object.keys(control.controls).forEach(key => {
control
.get(key)
?.valueChanges.pipe(takeUntil(this.destroy$))
.subscribe(checked => {
if (!checked) {
return;
}

if (key === noneKey) {
Object.keys(control.controls).forEach(k => {
if (k !== noneKey) {
control.get(k)?.setValue(false, { emitEvent: false });
}
});
} else if (control.get(noneKey)?.value === true) {
control.get(noneKey)?.setValue(false, { emitEvent: false });
}
});
});
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Optimizing control lookups and avoiding redundant setValue calls on controls that are already false prevents unnecessary form status/value updates and potential side effects.

  private applyNoneLogic(control: FormGroup, noneKey: string) {
    Object.keys(control.controls).forEach(key => {
      const childControl = control.get(key);
      childControl?.valueChanges
        .pipe(takeUntil(this.destroy$))
        .subscribe(checked => {
          if (!checked) {
            return;
          }

          if (key === noneKey) {
            Object.keys(control.controls).forEach(k => {
              if (k !== noneKey) {
                const otherControl = control.get(k);
                if (otherControl && otherControl.value !== false) {
                  otherControl.setValue(false, { emitEvent: false });
                }
              }
            });
          } else {
            const noneControl = control.get(noneKey);
            if (noneControl && noneControl.value === true) {
              noneControl.setValue(false, { emitEvent: false });
            }
          }
        });
    });
  }

Comment on lines 248 to 254
private getNoneOptionIndex(options: OptionType[] | undefined): number | null {
if (!options) return null;
return options.findIndex(option =>
const index = options.findIndex(option =>
this.getOptionValue(option)?.toLowerCase().includes('none')
);
return index !== -1 ? index : null;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If getOptionValue returns a non-string value (such as an object or a number), calling .toLowerCase() directly on it will throw a runtime TypeError. It is safer to explicitly check if the value is a string before calling string methods.

  private getNoneOptionIndex(options: OptionType[] | undefined): number | null {
    if (!options) return null;
    const index = options.findIndex(option => {
      const value = this.getOptionValue(option);
      return typeof value === 'string' && value.toLowerCase().includes('none');
    });
    return index !== -1 ? index : null;
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant