Hi there I am experiencing a really weird issue, formgroup value changes subscribed twice for a single change. Here are some code snippets which describes what I am trying to do. Unfortunately not able to create an stackblitz at the moment due some connectivity. numbers-only-input component html file
<mat-form-field appearance="outline" class="bsl-form-field-input">
<mat-label>{{ matLabel }}</mat-label>
<input
type="number"
matInput
[placeholder]="placeHolder"
[formControl]="formControl"
autocomplete="off"
appNumbersOnly
/>
</mat-form-field>
numbers-only-input component ts file
import { Component, Input, OnDestroy, OnInit, forwardRef } from '@angular/core';
import {
FormControl,
NG_VALUE_ACCESSOR,
NumberValueAccessor,
} from '@angular/forms';
import { Subject } from 'rxjs';
@Component({
selector: 'app-numbers-only-input',
templateUrl: './numbers-only-input.component.html',
styleUrls: ['./numbers-only-input.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NumbersOnlyInputComponent),
multi: true,
},
],
})
export class NumbersOnlyInputComponent
extends NumberValueAccessor
implements OnDestroy, OnInit
{
@Input()
formControl: FormControl;
@Input()
matLabel: string;
@Input()
placeHolder: string;
destroySubject = new Subject<void>();
ngOnDestroy(): void {
this.destroySubject.next();
this.destroySubject.complete();
}
ngOnInit(): void {
this.formControl.valueChanges.subscribe(value=>console.log(value))
}
}
numbers only directive file which is just preventing to enter any character except number and allowing paste values only for valid numbers.
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appNumbersOnly]',
})
export class NumbersOnlyDirective {
regEx = '^[0-9]+$';
// only numbers are allowed
@HostListener('keypress', ['$event'])
onKeyPress(event: KeyboardEvent) {
return new RegExp(this.regEx).test(event.key);
}
// block paste for non numeric values
@HostListener('paste', ['$event'])
onPaste(event: ClipboardEvent) {
const pastedString = event?.clipboardData?.getData('text/plain');
if (pastedString && !Number.isNaN(+pastedString)) {
return true;
} else {
return false;
}
}
}
You could use rxjs to reduce the number of calls. By taking the unique values and excluding multiple emissions through throttleTime
. Please find below a working example!
If this does not work please replicate the issue in the below stackblitz and share back!
ngOnInit(): void {
this.formControl.valueChanges
.pipe(
distinctUntilChanged(),
throttleTime(500),
takeUntil(this.destroySubject)
)
.subscribe((value) => console.log(value));
}