18

I am trying to integrate Google Sign In (link) using React.
I found a question that has solved this in past Using google sign in button with react 2

I replicated the same steps as mentioned. In my index.html I do

<script src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded" async defer></script>
    <script type="text/javascript">
        function triggerGoogleLoaded() {
            console.log("google event loaded");
            window.dispatchEvent(new Event('google-loaded'));
        }
    </script>

Then my Component looks like

var LoginButton = React.createClass({

    onSignIn: function(googleUser) {
        console.log("user signed in"); // plus any other logic here
    },

    renderGoogleLoginButton: function() {
        console.log('rendering google signin button');
        gapi.signin2.render('my-signin2', {
            'scope': 'https://www.googleapis.com/auth/plus.login',
            'width': 200,
            'height': 50,
            'longtitle': true,
            'theme': 'light',
            'onsuccess': this.onSignIn
        })
    },

    componentDidMount: function() {
        window.addEventListener('google-loaded',this.renderGoogleLoginButton);
    },

    render: function() {
        let displayText = "Sign in with Google";
        return (
            <div class="g-signin2" data-onsuccess="onSignIn"></div>
        );
    }

});

export default LoginButton;

When I run the program using yarn start, I get

/Users/Harit.Himanshu/bl/sources/webs/google-login/src/LoginButton.js
  11:9   error    'gapi' is not defined                             no-undef
  26:13  warning  'displayText' is assigned a value but never used  no-unused-vars

✖ 2 problems (1 error, 1 warning)

The complete source code is available at https://github.com/hhimanshu/google-login-with-react

Could someone please help me understand my mistake?

Thanks

6 Answers 6

26

It looks to me like you're loading the google apis as a script tag, which we'd expect to set window.gapi to the google api. However, you're then running eslint or some other checker, and that has no idea that window.gapi is supposed to exist. It's failing because it sees you using an undeclared variable.

A cheap fix is to tell Eslint that you know what you are doing;

/* global gapi */

Put this at the top of your file and eslint will treat gapi as a known global variable.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @steve, this has helped me to get get the button, now I am stuck with stackoverflow.com/questions/43767485/…, do you know where am I making mistake?
5

This worked for me. Put it in componentDidMount or constructor:

componentDidMount() {
    window.gapi.load('auth2', () => {
        // Retrieve the singleton for the GoogleAuth library and set up the client.
        this.auth2 = window.gapi.auth2.init({
            client_id: '436676563344-.apps.googleusercontent.com',
            cookiepolicy: 'single_host_origin',
        });

        this.auth2.attachClickHandler(this.refs.googleButton, {},
            (googleUser) => {
                this.googleLogin(googleUser.getBasicProfile());
            }, (error) => {

            });
    });
}

4 Comments

I still get the OP's error (Uncaught ReferenceError: gapi is not defined) with this. Are you defining gapi somewhere?
does you put <script src="apis.google.com/js/platform.js?onload=triggerGoogleLoaded" async defer></script> before your script ?
Do you know how I can get the gapi to work with react-native?
@Bomber sorry, but i don't know :(
5

You can also try the package gapi-script, this package provides the gapi instantly, so you don't have to wait any script to load, just import it and use:

import { gapi } from 'gapi-script';

3 Comments

Not a good solution since gapi script is updated by Google dynamically and this is just a hard copy of the script. You can end up with an outdated version of the script and your application may stop working.
Yes that's true and I agree with you, I don't recommend this package for companies and enterprise projects, only to small projects to study and etc.
The package was updated, now there is a function to download and use the real script from google's link.
2

Make sure that you’re not using async defer, which will cause race conditions between window.gapi.someMethod() and your script loading

In short, remove async defer from your script tag in your index.html.

before

<script src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded" async defer></script>

after

<script src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded"></script>

Comments

0

I had a simillar issue.

I use 'react-snap' for SEO. It blocked me to use 'gapi'. I found navigator.userAgent 'ReactSnap'.

if (navigator.userAgent !== 'ReactSnap') {
    // some code to dynamically load a script
    let myScript = document.createElement('script')
    myScript.setAttribute('src', 'https://apis.google.com/js/platform.js')
    document.body.appendChild(myScript)
}

I solved a problem. It works very well.

Comments

0

This workout helped me(place this code in index.html above main scripts):

    <script type="text/javascript">
      let tokenClient; // here you can pass client token after authentication
      let gapiInited = false;
      let gisInited = false;

      /**
       * Callback after api.js is loaded.
       */
      function gapiLoaded() {
        gapi.load("client", initializeGapiClient);
      }

      /**
       * Callback after the API client is loaded. Loads the
       * discovery doc to initialize the API.
       */
      async function initializeGapiClient() {
        gapiInited = true;
      }

      /**
       * Callback after Google Identity Services are loaded.
       */
      function gisLoaded() {
        gisInited = true;
      }
    </script>
    <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
    <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.