Search code examples
javascriptgoogle-authenticationcustom-element

Google Auth call back inside custom element


I'm trying to put google auth into a custom element using the code below. Its rendering correctly, and the button causes the regular google auth popup to fire, but after completing sign in, the callback is not triggered - none of the logs are triggered, and there is no error message. Any suggestions?

My guess is it has something to with the fact that I am using a class, as I read somewhere that the string needs to refer to a global function. But that's not possible in this context of course

customElements.define(
    "google-auth",
    class extends HTMLElement {
        constructor() {
            super();
            this._profile = {};
        }

        onSignIn(googleUser) {
            var profile = googleUser.getBasicProfile();
            console.log("ID: " + profile.getId()); // Do not send to your backend! Use an ID token instead.
            console.log("Name: " + profile.getName());
            console.log("Image URL: " + profile.getImageUrl());
            console.log("Email: " + profile.getEmail()); // This is null if the 'email' scope is not present.
            this._profile = profile;
        };

        connectedCallback() {
            console.log("google-auth");

            this.innerHTML = `
            <div class="g-signin2" data-onsuccess="onSignIn"></div>
        `;
        }
    }
);

Solution

  • You can also define the success callback explicitely as explained in the Google Auth documentation on custom Sign-In button.

    For example:

    connectedCallback() {
        console.log("google-auth");
    
        this.innerHTML = `
            <div id="my-signin2"></div>
        `;
    
        gapi.signin2.render('my-signin2', {
            'theme': 'dark',
            'onsuccess' : this.onSignIn.bind(this)
        });
    }
    

    If you do that, the Google library must be already loaded (that is: with no async defer attributes) when the connectedCallback() is called.

    If you want to keep the async defer attributes, you'll have to use a global render() function that will call a custom element method to render the button:

    function render() { 
        GA.render() // where GA is the custom element id
    }
    
    class extends HTMLElement {
       render() {
           gapi.signin2.render('my-signin2', 
           ...
       }
    }