0

This is my cutom dropdown search control value accessor . issue is when i set value in form control thats not getting selected in below control

 @Component({ selector: 'app-dropdown-search', templateUrl: './dropdown-search.component.html', styleUrls: ['./dropdown-search.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: DropdownSearchComponent, multi: true, }, ], }) export class DropdownSearchComponent implements OnInit, ControlValueAccessor, DoCheck { @Input() itemSource: any[] = [ { Id: 1, Value: 'Tom Cruise', }, { Id: 2, Value: 'Maria Sharapova', }, { Id: 3, Value: 'James Bond', }, ]; selectedValue: any; searchText: string = ''; isDisabled: boolean = false; onChange: any = () => {}; onTouched: any = () => {}; @ViewChild(MatAutocompleteTrigger) autocomplete!: MatAutocompleteTrigger; filteredOptions$!: Observable<any[]>; private searchTextSubject = new BehaviorSubject<string>(''); formControl!: FormControl; constructor( private injector: Injector, private errorStateMatcher: ErrorStateMatcher ) {} ngOnInit(): void { //setting form control this.setFormControl(); this.filteredOptions$ = this.searchTextSubject.pipe( debounceTime(100), distinctUntilChanged(), // Only emit if the value has changed map((text) => this.filterOptions(text)) ); } ngDoCheck(): void { if (this.formControl.value == null) { this.searchText = ''; this.searchTextSubject.next(''); } } setFormControl() { const ngControl = this.injector.get(NgControl); if (ngControl instanceof FormControlName) { this.formControl = this.injector .get(FormGroupDirective) .getControl(ngControl); } else { this.formControl = (ngControl as FormControlDirective) .form as FormControl; } console.log(this.formControl); } getFormControlErrorState(control: FormControl): boolean { return this.errorStateMatcher.isErrorState(control, null); } writeValue(value: any): void { this.selectedValue = value; } registerOnChange(fn: any): void { this.onChange = fn; } registerOnTouched(fn: any): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this.isDisabled = isDisabled; } selectOption(option: any): void { this.selectedValue = option; this.onChange(option); this.onTouched(); this.autocomplete.closePanel(); } onSearchTextChange(text: string): void { this.searchTextSubject.next(text); } filterOptions(text: string): any[] { if (text.trim() === '') { return []; } return this.itemSource.filter((item) => item.Value.toLowerCase().includes(text.toLowerCase()) ); } } 
<mat-form-field appearance="outline" class="form-field"> <mat-label>Employee</mat-label> <input matInput [placeholder]="'Search and Select...'" [formControl]="formControl" [(ngModel)]="searchText" [matAutocomplete]="auto" [class.invalid]="formControl.invalid && formControl.touched" (ngModelChange)="onSearchTextChange($event)" /> <mat-autocomplete #auto="matAutocomplete"> <mat-option *ngFor="let option of filteredOptions$ | async" [value]="option.Value" (click)="selectOption(option.Id)" > {{ option.Value }} </mat-option> </mat-autocomplete> <mat-error *ngIf="formControl.hasError('required')">Required</mat-error> </mat-form-field> 

When i set value for above cutom control thats not getting selected

 this.frmGroup = this.fb.group({ name: [1, Validators.required], isLocked: [{ value: false }], }); 
<div class="row"> <div class="col-md-4"> <app-dropdown-search formControlName="name"></app-dropdown-search> </div> </div> 

This above is my template form field of custom form control

I setting form control value like

 this.frmGroup = this.fb.group({ name: [1, Validators.required], isLocked: [{ value: false }], }); 

and also in template that i binding cutom control like

<div class="row"> <div class="col-md-4"> <app-dropdown-search formControlName="name"></app-dropdown-search> </div> </div> 

i expecting cutom control must be selected with itemsource of Id is 1

7
  • Have you tried to use trackBy when looping trough the mat-option? Commented Aug 13, 2023 at 17:10
  • Yes I tried like <mat-option *ngFor="let option of filteredOptions$ | async; trackBy: trackByFn" [value]="option.Value" (click)="selectOption(option.Id)" > {{ option.Value }} </mat-option> trackByFn(index: number, item: any): number { return item.Id; } Commented Aug 14, 2023 at 4:18
  • I tried by setting value manually also like this.frmGroup.get('name')?.setValue(1); I expecting dropdown should be preselected by option of Id is 1 Commented Aug 14, 2023 at 4:35
  • Why have you implemented ngDoCheck? This could be potentially a bottleneck.. have you tried to check if actually your abstractControl has been updated? frmGroup.valueChanges.subscribe(console.log)? Commented Aug 14, 2023 at 7:32
  • if i write formcontrol.valueChanges.subscribe() not satisfying that condition if (this.formControl.value == null) { this.searchText = ''; this.searchTextSubject.next(''); } Commented Aug 14, 2023 at 11:50

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.