Angular: debounceTime for dynamically generated input type

60 Views Asked by At

I have a list of cards. The list of cards is dynamic and the data is injected with @Input. Each card has a "description" input. The goal is that, when the 'description' input is updated (keyup), it automatically waits for 500ms (debounceTime) and then automatically emits the new value to parent component (that will dispatch the ngrx action).

Everything works perfectly but the "adding" of debounceTime. I tried to add the debounceTime using the viewChildren operator,fromEvent and AfterViewInit but the queryList is "undefined" even if i'm calling it inside the afterViewInit method. I expected the queryList is iterable as Angular documentation but it's not. The number of cards is dynamic, so i cannot use a formControl for valueChanges() method. Could you please indicate what am i missing?

export class ProductsDataComponent implements AfterViewInit{
  
  @ViewChildren('inputDesc', { read: ElementRef }) arrOfInputs!: QueryList<ElementRef>
  @Input() myborse!: IResource[];
  @Input() length!: number;
  @Input() pageSize!: number;
  @Input() pageSizeOptions!: number[];
  @Output() emitterBin: EventEmitter<string> = new EventEmitter();
  @Output() emitterUpdateBorsaTracking: EventEmitter<IProductCardUpdateTracking> = new EventEmitter();
  @Output() emitterUpdateBorsaDescription: EventEmitter<IProductCardUpdateDescription> = new EventEmitter();
  @Output() emitterPageChange: EventEmitter<PageEvent> = new EventEmitter();

  
  ngAfterViewInit(): void {
    this.arrOfInputs.forEach(input=>{
      fromEvent(input.nativeElement, 'keyup').pipe(
        debounceTime(500)
      )
      .subscribe(res => console.log('emitEvent to parent. This line is never triggered'));
    })
  }
 onChange=(id:string)=>{

  }
}
<div class="row">

    <div class="col-sm-6 col-md-4 col-12 col-lg-3" *ngFor="let borsa of myborse">
        <div *ngIf="borsa!==undefined">
            <mat-card class="example-card">
                <mat-card-header>
                    ...
                </mat-card-header>
                <div>
                    <ngb-carousel #carousel>
                        ...
                    </ngb-carousel>
                </div>

                <mat-card-content>
                    <mat-form-field class="example-form-field" appearance="outline">
                        <input matInput type="text" #inputDesc id={{borsa._id}} value="{{borsa.description}}"
                            placeholder="Description"
                            (input)="onChange(borsa._id)"
                            >
                    </mat-form-field>
                </mat-card-content>
                <mat-card-actions>
                    ...
                </mat-card-actions>
            </mat-card>
        </div>
    </div>
</div>
<mat-paginator #paginator 
    ...
</mat-paginator>
1

There are 1 best solutions below

2
Ricudo On

If everything works perfectly without debounceTime, it must be change detection issue. You can inject ChnangeDetectorRef an manually say angular to detect the changes. If it won't help you can change approach to not react on each event directly and use setTimeout for delay 500ms