Angular: How to reset matChipList input field and Google Recaptcha?

Viewed 1508

I have an input field in a form where the candidate has to enter his skills. So I made a chip input field. The problem is when I am resetting the form the value from chip gets cleared but the chip view stays. I have followed this example for MatChips but nothing works. Below is my code:

TS

@ViewChild('chipList') chipList: MatChipList;
@ViewChild('tags') tags: ElementRef;

profileForm = this.fb.group({tag: this.fb.array([]),
    Recaptcha: [false, Validators.requiredTrue]
});

add(event: MatChipInputEvent, form: FormGroup): void {
    const input = event.input;
    const value = event.value;
    // Add name
    if ((value || '').trim()) {
      const control = <FormArray>form.get('tag');
      control.push(this.initName(value.trim()));
    }
    // Reset the input value
    if (input) {
      input.value = '';
    }
}

remove(form, index) {
  form.get('tag').removeAt(index);
}

get Tags() {
  return this.profileForm.get('tag');
}

get ReCaptcha() {
    return this.profileForm.get('Recaptcha');
}

registerUser(formDirective: FormGroupDirective) {
  for(let i of this.Tags.value) {
    this.skills += i + ',';
  }
  this.skills = this.skills.substring(0, this.skills.length-1);
  this.profileForm.patchValue({
    skills: this.skills,
    mobileNumber: this.MobileNumber.value.replace(/\-/gi, '')
  });
  if(this.ReCaptcha.value == true) {
    this.appService.userRegistration(this.profileForm.value).subscribe(response => {
      if(response.message != "Success.") {
        this.snackbarService.class = 'red-snackbar';
        return this.snackbarService.open('User Registration Unsuccessfull');
      }
      this.router.navigate(['/login']);
      this.snackbarService.class = 'green-snackbar';
      this.snackbarService.open('User Registered Successfully');
    }, error => {
      this.snackbarService.class = 'red-snackbar';
      this.snackbarService.open('Something went wrong');
    });
    formDirective.resetForm();
    this.profileForm.reset();
    this.tags.nativeElement.value = '';
  }
}

HTML

<div class="row">
  <div class="col-md-12">
    <mat-form-field class="example-chip-list" appearance="outline" style="width: 100%;">
      <mat-label>Skills</mat-label>
      <mat-chip-list #chipList formArrayName="tag" matTooltip="Press Enter to seperate skills">
        <mat-chip *ngFor="let name of profileForm.get('tag')['controls']; let i=index;"
          [selectable]="selectable" [removable]="true" (removed)="remove(profileForm, i)">
          {{name.value}}
          <mat-icon matChipRemove *ngIf="true">cancel</mat-icon>
        </mat-chip>
        <input #tags [matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
          [matChipInputAddOnBlur]="addOnBlur" (matChipInputTokenEnd)="add($event, profileForm)">
      </mat-chip-list>
    </mat-form-field>
  </div>
</div>

<recaptcha formControlName="Recaptcha" (scriptError)="onScriptError()"></recaptcha>
<button type="submit" class="float-right" [disabled]="profileForm.invalid || !ReCaptcha"
  class="btnRegister btn">Register</button>

app.module

import { RecaptchaModule } from 'angular-google-recaptcha';

@NgModule({
    imports: [
    RecaptchaModule.forRoot({
      siteKey: 'SITE_KEY'
    })
]
})

This is the current scenario after I hit the register button: enter image description here

3 Answers

You could try to divide in two distinct forms, one for your data one for recaptcha.

By this way the recaptcha reset should not affect your data form

The issue may lie when you implement the tag control as a form array. It doesnt store an array of controls, but an array of values. I've made a basic stackblitz with a 'clear form' button to hopefully simulate what you're trying to achieve.

You have to initialize the tag formControl with an empty array and when resetting the form, make sure that it is also set it to an empty array.

https://stackblitz.com/edit/angular-tn3nai

Change this line

this.tags.nativeElement.value = '';

to

this.tags.nativeElement.value = null;
Related