ng-recaptcha tag <recaptcha> causes error “zone.js: Unhandled Promise rejection” when route changes
[Maintainer update 2022-09-26]
Please see this comment.
Summary
I'm submitting a:
- [x] bug report
Description
I'm using "ng-recaptcha" on Angular component. Im using inside a form like this:
<form class="form-contact"
[formGroup]="contactForm"
#formDirective="ngForm"
(ngSubmit)="sendMessage(contactForm, formDirective)">
<re-captcha class="recaptcha"
formControlName="captcha"
siteKey="mysitekey">
</re-captcha>
</form>
Everything seems to be working fine. However, when route changes (ex. user goes to another page) and the AboutComponent is rendered again, an error pops up (multiple times): Unhandled Promise rejection: timeout ; Zone:

- [x] I did my best to come up with a Minimal, Complete, and Verifiable example
https://stackblitz.com/edit/angular-en3spw
Lib versions:
- ng-recaptcha: 4.0.0-beta.1
- Angular: 6.1.4
- Typescript (
tsc --version): 2.9.2
It's not necessary to reload a component to get this error - destroying a component containing recaptcha leading to this case PS. This problem is also present in version 3.0.5 of ng-recaptcha
Does anyone know of a work around with this?
I had the same error message, but in my case captcha doesn't load anymore ...
I have 2 forms with captcha, first time the captcha render properly, but when i navigate between them captcha doesn't load anymore.
Only workaround i've found : on form component destroy, remove the captcha element from DOM
@ViewChild('captchaRef')
reCaptcha: RecaptchaComponent;
...
ngOnDestroy() {
const captchaElem = this.reCaptcha['elementRef'].nativeElement;
captchaElem.parentElement.removeChild(captchaElem);
}
Now captcha always load properly, but error message continue to show up...
I have the same issue, when the error shows up it breaks some other TS I have running on the next page.
EDIT: I have a guess as to what this is coming from. Seems like the issue is a call to a specific Google URL: https://www.google.com/recaptcha/api2/anchor?[more URL parameters]. Upon navigating away, the library apparently tries to reach this URL, and it just stays at "(Pending)" in dev tools.
Hey folks! Thx for letting me know about this, and I’m sorry that getting back to you took so long.
At this point I think I know where the issue is, ~and I plan to release a fix for it in the next couple of days in the 4.x.x branch.~ and I've reached out to recaptcha support team, see my comment below
To not keep you folks in the dark, here's a small status update.
Why it happens?
This error happens due to the following scenario:
- When the component is destroyed,
ng-recaptchainvokes thegrecaptcha.reset(ID)method - This results in recaptcha invoking the
api2/anchorendpoint that @BrentACole mentions - For some reason this endpoint times out
- Since this unhandled promise lies inside
recaptcha__en.jsfile there's no way we could catch it (e.g. patching this file is not an option given such a sophisticated minimization algorithm used)
Why not just skip invoking grecaptcha.reset during ngOnDestroy?
It's there for a reason, and this reason is #10 .
What can I do?
If you can - ignore it. Add this error to an allowlist in your e2e tests or frontend monitoring software.
Otherwise, you can override the ngOnDestroy method of RecaptchaComponent manually (or create a component fork). Please be aware, that this is a temporary and pretty bad fix that might put you in a very unfortunate position when upgrading component versions! Nevertheless, here's approximate code for that:
// somewhere in your "main.ts"
import { RecaptchaComponent } from 'ng-recaptcha';
RecaptchaComponent.prototype.ngOnDestroy = function() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
What next?
I've submitted this issue to the recaptcha support team, and I'll post an update here when I have it.
Thx for bearing with me on that!
Hey @DethAriel, can you paste the link to the recapcha issue you created?
@SirWojtek the recaptcha core team does not have a public bug tracker (at least not one that I know of). I've submitted an issue to their support team through email, and I followed up again today. First time they recommended me to submit a question to StackOverflow, which I did with no results so far.
Let's see if they get back with some hints/workarounds/timelines anytime soon. I would be very happy to bring you the good news today, but right now this is all I've got
I had someone Ina discord give me something like this which works most of the time but sometimes will still throw errors.
@ViewChild('captcha') captcha: ElementRef;
@ViewChild('submit') submit: MatButton;
captchaConnection;
renderCaptcha() {
if (!grecaptcha.render) {
setTimeout(() => {
grecaptcha.render(this.captcha.nativeElement, {
callback: (e) => this.captchaCallback(e)
});
}, 2000)
}
grecaptcha.render(this.captcha.nativeElement, {
callback: (e) => this.captchaCallback(e)
});
}
@ErraticFox it does not look like this is solving the issue, could you please elaborate on what you mean by "works most of the time"? These errors are thrown when recaptcha is removed from DOM, not when it's rendered
Anyone solved this error ? I had the same error on angular 4 with recaptcha.
Trying @DethAriel's workaround on Angular 7, I'm getting:
ERROR in src/main.ts(23,12): error TS2339: Property 'subscription' does not exist on type 'RecaptchaComponent'.
@DethAriel also writes
this is a temporary and pretty bad fix that might put you in a very unfortunate position when upgrading component versions
I am not sure what this means? If it is pretty bad, does it not actually fix the bug?
hm, I tried overiding the destroy event as suggested in https://github.com/DethAriel/ng-recaptcha/issues/123#issuecomment-426112101
and doesn't seems to have any effect
now with the @DethAriel https://github.com/DethAriel/ng-recaptcha/issues/123#issuecomment-426112101
throws:

@matudelatower seems to still work fine for me (see this example), but as I mentioned, this is not a fix, and my current suggestion is to ignore this error and add it to the allow-list in the frontend monitoring tools.
If someone is facing this issue in ionic/cordova app, i solved it by setting in config.xml, this would also need cordova whitelist plugin
Has anybody found a solution to avoid this?
Hello anybody found a solution, now ? maybe we can load script outside angular ? or catch errors manual ?
I am still testing, but this seemed to work for me.
import { FormControl, Validators } from '@angular/forms';
import { RecaptchaComponent } from 'ng-recaptcha';
public captchaEl: FormControl = new FormControl(null, Validators.required);
ngOnInit(): void {
RecaptchaComponent.prototype.ngOnDestroy = function() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
this.captchaEl.reset();
}
Then after the form is submitted, I do this.captchaEl.reset(); again. Still testing, but I am not seeing the error anymore.
@DethAriel any other updates or responses from the reCaptcha team?
Google sadly has a bad habit of not providing cleanup functions for their APIs. reset() is semantically wrong method anyway, there should be a destroy() call.
I have played around a lot with simplified version of the project, having static grecaptcha api loaded in index.html and a tiny component with grecaptcha.render in ngAfterViewInit and different cleanup experiments in ngOnDestroy. I have failed to get it working reliably. Creating and destroying the component multiple times either leaks memory, results an error or both.
To not keep you folks in the dark, here's a small status update.
Why it happens?
This error happens due to the following scenario:
- When the component is destroyed,
ng-recaptchainvokes thegrecaptcha.reset(ID)method- This results in recaptcha invoking the
api2/anchorendpoint that @BrentACole mentions- For some reason this endpoint times out
- Since this unhandled promise lies inside
recaptcha__en.jsfile there's no way we could catch it (e.g. patching this file is not an option given such a sophisticated minimization algorithm used)Why not just skip invoking
grecaptcha.resetduringngOnDestroy?It's there for a reason, and this reason is #10 .
What can I do?
If you can - ignore it. Add a whitelist for this error in your e2e tests or frontend monitoring software.
Otherwise, you can override the
ngOnDestroymethod ofRecaptchaComponentmanually (or create a component fork). Please be aware, that this is a temporary and pretty bad fix that might put you in a very unfortunate position when upgrading component versions! Nevertheless, here's approximate code for that:// somewhere in your "main.ts" import { RecaptchaComponent } from 'ng-recaptcha'; RecaptchaComponent.prototype.ngOnDestroy = function() { if (this.subscription) { this.subscription.unsubscribe(); } }What next?
I've submitted this issue to the recaptcha support team, and I'll post an update here when I have it.
Thx for bearing with me on that!
Hi! Any news from google
Hey @DethAriel have you tried moving the offending logic outside a zone?
constructor(private ngZone: NgZone) {
}
...
this.ngZone.runOutsideAngular(() => {
// reCAPTCHA logic here
})
https://angular.io/api/core/NgZone#runoutsideangular
Just a thought!
@johngrimsey No, it does not help.
Ah well. Still, great lib man.
Could this be of some help? I'm on mobile so it's difficult to check, but thought I'd share so someone else could try this. Worth a shot. https://github.com/google/recaptcha/issues/269#issuecomment-606838861
anyone found a fix for it? I'm still seeing this in version 5
As a temporary solution, I use a RouteReuseStrategy. This allows you not to destroy the page (route) where the captcha is used, but to save it to the cache. As a result, the ngOnDestroy method for this component is never called and no error is thrown. The downside of this solution is that the component remains in memory, but in my case it is a small page with a feedback form, so I decided simply ignore it.
Just adding to this bug. I'm getting the same error using the latest version of ng-recaptcha, but the issue now points to zone.evergreen.js. The original solution provided using main.ts also seems to have no effect. Going to keep working on this issue, but just wanted others to know it can also appear as zone.evergreen.js

Just adding to this bug. I'm getting the same error using the latest version of ng-recaptcha, but the issue now points to zone.evergreen.js. The original solution provided using main.ts also seems to have no effect. Going to keep working on this issue, but just wanted others to know it can also appear as zone.evergreen.js
I am also experiencing this! :(