I've a material drop down box as follows with a select event (selectionChange):
<mat-select #segmentSelector [formControlName]="filter.VAL" multiple placeholder="Select" (selectionChange)="someMethod($event.value, filter.VAL)">
<div class="custom-panel">
<ng-container *ngFor="let option of getFilterDropdownOptions(filter.VAL)">
<mat-option *ngIf="!!option" [value]="option" [value]="option">
{{ option }}
</mat-option>
</ng-container>
</div>
<footer class="select-box-footer">
<a class="select-box-footer-btn" (click)="$event.preventDefault();segmentSelector.close();">Done</a>
</footer>
</mat-select>
This works fine as it gets triggered whenever I change the value in the dropdown as follows:
someMethod(val: any, columnName: any) {
console.log(val);
var obj = val as [];
if (columnName === "CUST_ID") {
this.aLogData.customerId = [];
for (var i = 0; i < obj.length; i++) {
console.log(obj[i]);
this.aLogData.customerId.push(obj[i]);
}
}
if (columnName === "CUST_NAME") {
this.aLogData.customerName = [];
for (var i = 0; i < obj.length; i++) {
console.log(obj[i]);
this.aLogData.customerName.push(obj[i]);
}
}
var searchLocationInput = ((document.getElementById("searchLocationInput") as HTMLInputElement).value);
console.log(this.aLogData);
console.log(searchLocationInput);
this.aLogData.searchItem = searchLocationInput;
this.statusTwo = true;
setTimeout(() => this.delaySomeMthod(this.aLogData), 10000); //Trying to delay to send data once
}
delaySomeMthod(aLogData: LogData) {
console.log("Called after 10 secs.");
this.locationService.setLogData(aLogData).subscribe();
}
Now the issue is whenever I select or change data in the dropdown it gets triggered and calls the controller each time. I was trying to put a timer to make that work but seems like I require to check to send the request to the controller once and at a certain time interval.
So my requirement is select or change values with dropdown box multiple times, but call the service or controller once after a certain time say 10 secs as I am adding data in an array. Is it something doable?
You can simply write a decorator
to perform this action. The method will not fire until the stipulated time has passed. you can keep it in a separate TS file and use it throughout your application (great for reusability).
export function ngDebounce(timeout: number) {
// store timeout value for cancel the timeout
let timeoutRef = null;
return function(target, propertyKey: string, descriptor: PropertyDescriptor) {
// store original function for future use
const original = descriptor.value;
// override original function
descriptor.value = function(...args) {
// clear previous timeout
clearTimeout(timeoutRef);
// sechudle timer
timeoutRef = setTimeout(() => {
// call original function
original.apply(this, args);
}, timeout);
}
// return descriptor with new value
return descriptor;
}
}
@ngDebounce(10000)
delaySomeMthod(aLogData: LogData) {
console.log("Called after 10 secs.");
this.locationService.setLogData(aLogData).subscribe();
}