Search code examples
angularangular-reactive-formsrecaptcha-v3

Angular reactive forms with reCAPTCHA v3


I want to send form together with captcha token to backend. In my .ts file I have:

buildForm() {
    this.form = this.fb.group({
      email: [null, Validators.required],
      firstName: [null, Validators.required],
      lastName: [null, Validators.required],
      company: [null],
      captcha: [null]
    });
  }

executeRecaptcha() {
    this.recaptchaV3Service.execute('submitForm').subscribe(
      token => {
        console.log('Recaptcha v3 token', token);
        this.form.patchValue({captcha: token});
      },
      error => {
        console.log(`Recaptcha v3 error: see console`);
        console.log(`Recaptcha v3 error:`, error);
      }
    );
  }

submitForm() {
    super.submitForm();
    const data = getFormDataWithCaptcha<MyType>(this.form.getRawValue());
    console.log(data.captcha);
    if (this.form.invalid) {
      this.onValueChanged(data);
    } else {
      this.loader = this.registerService.registerUser(data).subscribe(
        () => {
          this.messages.show('REGISTERED', 'success');
        }
      );
    }
  }

My template:

<div class="d-flex justify-content-center form-buttons">
      <button class="btn  btn-primary" (click)="executeRecaptcha()"
              type="submit">{{ 'REGISTER' }}</button>
</div>

I know that I can't asign the token to captcha with subscribe because it's asynchronious action. What's the best way to implement it?

I want to use recaptcha v3 so the user doesn't have to click anything.

I read the docs several times: https://developers.google.com/recaptcha/docs/v3 but it's vague to me. I was also following this guide: https://nicedoc.io/DethAriel/ng-recaptcha#installation and searching all over the internet but can't grasp it.

So can I use recaptcha v3 with reactive forms? Am I going in the right direction with it and if not what's the proper aproach? Also I would be greatful for any explanation and pointing out my thought process errors.


Solution

  • You don't need click listener on submit button, you just should make a request for captcha token before registerUser request.

    I didn't get your conditions on form submit, but token can be easily added to form data with RxJS switchMap operator and will look like:

    onSubmit(): void {
       this.recaptchaV3Service.execute('submitForm').pipe(
          map((token) => ({...this.form.getRawValue(), captcha: token})),
          switchMap((formData) => this.registerService.registerUser(formData))
       )
    }