0

I have a search input and I only want to trigger the this.searchProperties.emit if the user touch or made an input to the input field I don't wanna trigger it after view init. I only want to emit if the user touches or made an input on the input field.

Currently, the issue is it calls the emit after the view is initialized. Thanks for any ideas or help.

html code

<mat-form-field id="property-list-filter" appearance="fill">
      <mat-label style="font-size:12px">Filter properties</mat-label>
      <input matInput #searchInput placeholder="Ex. Property ID" #input>
</mat-form-field>

ts code snippet

@ViewChild('searchInput') searchInput: ElementRef;
ngAfterViewInit() {
    this.dataSource.sort = this.sort;
    this.dataSource.paginator = this.paginator

    fromEvent<any>(this.searchInput.nativeElement, 'keyup')
      .pipe(
        map((event) => event.target.value),
        startWith(''),
        debounceTime(500),
        distinctUntilChanged(),
        switchMap(async (search) => {
          this.searchProperties.emit(this.searchInput.nativeElement.value.trim().toLowerCase())
        })
      )
      .subscribe({ complete: noop });
}
3
  • event is emitted because you have startWith(''), so you stream doing all logic Commented Nov 29, 2022 at 10:03
  • so what would be your suggestion Sir ? , if we remove that startWith and then user empty or erase the search input how do will call the emit again ? Commented Nov 29, 2022 at 10:04
  • 1
    Use a FormControl instead of that ElementRef and then listen to the value changes of that control. Commented Nov 29, 2022 at 10:15

2 Answers 2

2

I suggest you, use the ngModel and ngModelChange

<mat-form-field id="property-list-filter" appearance="fill">
  <mat-label style="font-size:12px">Filter properties</mat-label>
  <input matInput [(ngModel)]="input variable" (ngModelChange)="changeHandlerFunction()" placeholder="Ex. Property ID" #input>
</mat-form-field>

check this link

Sign up to request clarification or add additional context in comments.

Comments

1

First of all, remove the startWith from your pipes. It triggers an emit on first initialization.

In order to track an input event, you have to listen to it with Angular event binding like this:

<input (input)="onInput()"/>

And in your ts file:

onInput(){
    ...
}

In order to listen to user input-touch, you can listen in the same way to the focus event or to other events that fit your need.

In addition, I recommend you to use the Angular's ReactiveForms API to manage the input state. You will find ther everythging you need in a smart and reactive way. Here is a link.

3 Comments

but I need the debounce time for the search how will I apply that with your logic/code?
You can leave the debounce there, just remove the startWith
If you will use the reactiveForms API, You'll be able to listen to input changes and apply any rxjs pipe on it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.