How to use gapi in react
Asked Answered
M

3

11

I want to use gapi to access people api resources from google, I tried many ways to do the job, but I still cannot get any response. It has not error, no warning. Here is my code.

loadYoutubeApi() {
    const script = document.createElement("script");
    script.src = "https://apis.google.com/js/client.js";

    script.onload = () => {
      window.gapi.load('client', () => {
        window.gapi.client.setApiKey(types.API_KEY)
        window.gapi.client.setClientId(types.CLIENT_ID)
        window.gapi.client.setDiscoveryDocs(types.DISCOVERY_DOCS)
        window.gapi.client.setScope(types.SCOPE)
        window.gapi.client.load('client:auth2', 'v3', () => {
          console.log("gapi is ready")
          this.setState({ gapiReady: true });
        });
      });
    };

    document.body.appendChild(script);
  }

  componentDidMount() {
    this.loadYoutubeApi();
  }

Can anyone tell me why I cant even get the console log info, is it actually working?

Update:

Once I commented these codes out

window.gapi.client.setClientId(types.CLIENT_ID)
window.gapi.client.setDiscoveryDocs(types.DISCOVERY_DOCS)
window.gapi.client.setScope

I can get my console info, is it something to do with those methods?

Update:

I can get gapi object and console.log(window.gapi) to see its detail.

Mouthwash answered 23/8, 2018 at 2:12 Comment(4)
Possible duplicate of Load external javascript through script tagEnsconce
Also you can look at this: github.com/facebook/create-react-app/issues/2203Ensconce
@David Kamer Thanks, I tried those methods before, but none of them work to meMouthwash
Let me know if you have any trouble finding the folder I'm talking about. I know that adding it directly to the index.html file works because that is how I personally load all non-react scripts. If you are hell bent on loading it in the component you might try adding .call() at the end of onload, but I don't think it will work.Ensconce
E
11

Assuming you are using create-react-app and you have webpack configured with a public HTML folder, than that is where you will need to place your script tag.

You may not see your public folder in certain text editor project trees, but you will see it in your OS file browser. Simply go to the public folder and edit index.html with the line:

<script src="https://apis.google.com/js/client.js"></script>

right above the closing </head> tag. You are doing this indirectly with your current code anyway. You can remove:

 const script = document.createElement("script");
 script.src = "https://apis.google.com/js/client.js";

and the onload call, placing all of your api object calls (with window as the base object) in your componentDidMount() method. You don't have to worry about it being loaded as your component can only mount after everything is loaded.

Also, don't worry about it slowing anything down or loading the script before you need it. When you run npm run build before production you will condense everything into a few files anyway.

EDIT:

You should change your onload call to addEventListener('load', callback);

Ensconce answered 23/8, 2018 at 2:44 Comment(6)
Also pop into your manifest in the public directory for a cool bonus file to fix up for your application!Ensconce
No, I can get the gapi package, and I can see the object detail once I console.log(window.gapi). The problem is once I set my clientId, discoveryDoc, and scope, I can't get the response.Mouthwash
Are you treating the request as an async promise?Ensconce
yes, so how should I add sync so it can wait until the gapi package is fully initializedMouthwash
after looking at it again, have you tried changing it to adding to the index.html file? That would solve the problem if it isn't fully initialized.Ensconce
https://mcmap.net/q/770390/-script-load-in-react might also answer if you can't do that. You might have to create a function outside of your class that promisifies your script load. Or you could just try script.addEventListener('load', callback) instead of onload. I think onload is an old jQuery method that won't work unless you added that for some odd reason.Ensconce
G
20

I had a lot a problems trying to add the gapi at my react project. All the packages that I found were outdated, so I created a new one.

gapi-script allow you to add gapi with:

import { gapi } from 'gapi-script'
Gourmet answered 17/7, 2019 at 20:50 Comment(1)
this library has broken my webpack, not sure what to do about itBengt
E
11

Assuming you are using create-react-app and you have webpack configured with a public HTML folder, than that is where you will need to place your script tag.

You may not see your public folder in certain text editor project trees, but you will see it in your OS file browser. Simply go to the public folder and edit index.html with the line:

<script src="https://apis.google.com/js/client.js"></script>

right above the closing </head> tag. You are doing this indirectly with your current code anyway. You can remove:

 const script = document.createElement("script");
 script.src = "https://apis.google.com/js/client.js";

and the onload call, placing all of your api object calls (with window as the base object) in your componentDidMount() method. You don't have to worry about it being loaded as your component can only mount after everything is loaded.

Also, don't worry about it slowing anything down or loading the script before you need it. When you run npm run build before production you will condense everything into a few files anyway.

EDIT:

You should change your onload call to addEventListener('load', callback);

Ensconce answered 23/8, 2018 at 2:44 Comment(6)
Also pop into your manifest in the public directory for a cool bonus file to fix up for your application!Ensconce
No, I can get the gapi package, and I can see the object detail once I console.log(window.gapi). The problem is once I set my clientId, discoveryDoc, and scope, I can't get the response.Mouthwash
Are you treating the request as an async promise?Ensconce
yes, so how should I add sync so it can wait until the gapi package is fully initializedMouthwash
after looking at it again, have you tried changing it to adding to the index.html file? That would solve the problem if it isn't fully initialized.Ensconce
https://mcmap.net/q/770390/-script-load-in-react might also answer if you can't do that. You might have to create a function outside of your class that promisifies your script load. Or you could just try script.addEventListener('load', callback) instead of onload. I think onload is an old jQuery method that won't work unless you added that for some odd reason.Ensconce
D
11

I made a custom Hook for this!

import { useEffect } from 'react';

const useGoogle = () => {

    useEffect(() => {

        const SCOPE = "TODO: your scope here";
        const handleClientLoad = () => window.gapi.load('client:auth2', initClient);
    
        const initClient = () => {
            const discoveryUrl = "TODO: your discoveryUrl here";
            window.gapi.client.init({
                'clientId': "TODO: your client id here",
                'discoveryDocs': [discoveryUrl],
                'scope': SCOPE
            });
            console.log("Google loaded");
        };

        const script = document.createElement('script');

        script.src = "https://apis.google.com/js/api.js";
        script.async = true;
        script.defer = true;
        script.onload = handleClientLoad;

        document.body.appendChild(script);

        return () => {
            document.body.removeChild(script);
        };

    }, []);
};

export default useGoogle;
Damage answered 29/1, 2022 at 1:37 Comment(1)
I'm getting this error when I try to use gapi: API keys are not supported by this API. Expected OAuth2 access token or other authentication credentials that assert a principal.Clarke

© 2022 - 2024 — McMap. All rights reserved.