1

Having trouble with a reCaptcha module in a Polymer 1 app.

I can use this module once (on the register form) but if I try to use it on any other component results in an error: Uncaught Error: reCAPTCHA has already been rendered in this element.

  • Initially thought the problem was because I loaded the recaptcha script inside the module so I moved that to index.html. But the problem continues to persist.

  • Tried using grecaptcha.reset() in various places to unload the widget so it can be rendered in other components.

Inside recaptcha-module-html:

<dom-module id="recaptcha-module">
    <template>
        <div class="captcha-container">
            <div id="captcha"></div>
        </div>
    </template>
    <script>
        Polymer({
            is: "recaptcha-module",
            ready: function () {
                this.recaptchaCallback = this.recaptchaCallback.bind(this)
                this.recaptchaExpired = this.recaptchaExpired.bind(this)
                window.recaptchaCallback = this.recaptchaCallback
                window.recaptchaExpired = this.recaptchaExpired
            },

            attached: function () {
                grecaptcha.render('captcha', {
                    'sitekey': {SITE_KEY_HERE}
                    'size': 'compact',
                    'callback': 'recaptchaCallback',
                    'expired-callback': 'recaptchaExpired'
                });
            },

            recaptchaCallback: function () {
                this.fire('recaptcha-success')
            },

            recaptchaExpired: function () {
                this.fire('recaptcha-expired')
            }

        });
    </script>
</dom-module>

Loading the recaptcha script in index.html:

  <script src="https://www.google.com/recaptcha/api.js">
  </script>

How I try to load the recaptcha-module in other components:

<link rel="import" href="recaptcha-module.html">
...
<recaptcha-module></recaptcha-module>

I expect that the module can be imported and used in multiple form components with but doing so causes an error and the widget refuses to be loaded more than once.

0

1 Answer 1

0

This issue was caused because the module did not assign a unique ID to the placeholder reCaptcha element. In order to fix the issue I created a property called elementid that could be used to give each render of the reCaptcha element a unique ID.

<dom-module id="recaptcha-module">
    <template>
        <div class="captcha-container">
            <div class="captcha" id="[[elementid]]"></div>
        </div>
    </template>
    <script>
        Polymer({
            is: "recaptcha-module",
            properties: {
                elementid : String,
                captchastyle : String
            },
            ready: function () {
                this.recaptchaCallback = this.recaptchaCallback.bind(this)
                this.recaptchaExpired = this.recaptchaExpired.bind(this)
                window.recaptchaCallback = this.recaptchaCallback
                window.recaptchaExpired = this.recaptchaExpired
            },

            attached: function () {
                grecaptcha.render(this.elementid, {
                    'sitekey': {MY_SITE_KEY},
                    'size': this.captchastyle,
                    'callback': 'recaptchaCallback',
                    'expired-callback': 'recaptchaExpired'
                });
            },

            recaptchaCallback: function () {
                this.fire('recaptcha-success')
            },

            recaptchaExpired: function () {
                this.fire('recaptcha-expired')
            }

        });
    </script>
</dom-module>

Then you can import the module and use the custom element anywhere else by giving it a unique ID. Like so:

<recaptcha-module elementid="UNIQUE_ID" captchastyle="normal"></recaptcha-module>

Not the answer you're looking for? Browse other questions tagged or ask your own question.