Angular Query-builder: How to lazily load data for options (possible values) for material auto-complete

1.8k views Asked by At

I am currently working with Angular-QueryBuilder and updating templates for with ng-container with .

  <!-- Override input component for 'category' type -->
  <ng-container *queryInput="let rule; let field=field; let options=options; type: 'category'">
    <mat-form-field class="categoryValue" floatLabel="never">
      <mat-select [(ngModel)]="rule.value" [placeholder]="field.name">
        <mat-option *ngFor="let opt of options" [value]="opt.value">
          {{ opt.name }}
        </mat-option>
      </mat-select>
    </mat-form-field>
  </ng-container>

My requirement is to load the data for options dynamically. i.e. loading data for this fields from the server after user starts typing (I will be using mat-auto-complete instead of mat-select). I am facing some challenges while creating stackblitz for the example. (so far: https://stackblitz.com/edit/angular-8-material-starter-template-lpmxwi)

enter image description here

If anyone has implemented something like that or give some direction, it would be really great.

Update:

Would like to highligh that using material auto-complete is not an issue. Integrating auto-complete and updating values for it dynamically for query-builder component is the issue. Query-builder is not populating the values if I update it programatically after its initialization like below.

  onFieldChange ($event, rule) { // gets called when I change the field dropdown
    if (this.params.config.fields[$event].type === 'category') {
        // updating 'options' (like male and female) dynamically
        // in actual scenario, I will be calling server to get its' values
        this.params.config.fields[$event].options = [
          { name: 'Aaa', value: 'a' },
          { name: 'Bbbb', value: 'b' },
          { name: 'Cccc', value: 'c' },
          { name: 'Dddd', value: 'd' }
        ];
    }
  }
1

There are 1 answers

1
Stefan On

What you can do is creating a FormControl for your input where you will be typing

myControl = new FormControl();

And then associate it to your input within HTML

<input type="text"
       placeholder="Search"
       aria-label="Search"
       matInput
       [formControl]="myControl"
       [matAutocomplete]="auto">

And finally, within your component listen for the value changes and request new data which then you will set as your options

this.myControl.valueChanges
  .pipe(
    filter(searchPhrase => !!searchPhrase),
    debounceTime(500),
    distinctUntilChanged(),
    takeUntil(this.ngUnsubscribe) // optional but recommended 
  )
  .subscribe(searchPhrase => this.service.searchMyOptions(searchPhrase));