Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React- only run file once external js file loaded (gapi not defined)

I am trying to use the gmail API with React.js.

I keep getting the error 'gapi is not defined'. I believe my client.js file in the HTML is loading after my mail.js file runs?

How can I get around this?

Index.html

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

Index.js

import './Mail.js';

Mail.js

import { createAction, handleActions } from 'redux-actions'

const CLIENT_ID = '1.apps.googleusercontent.com'
const SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']

export const SET_GMAIL_CREDENTIALS = 'SET_GMAIL_CREDENTIALS'
export const CHANGE_LOADING = 'CHANGE_LOADING'
export const SET_GMAIL_LABELS = 'SET_GMAIL_LABELS'
export const SELECT_GMAIL_LABEL = 'SELECT_GMAIL_LABEL'
export const SET_GMAIL_EMAILS = 'SET_GMAIL_EMAILS'

let defaultState = {
  profile: {
    emailAddress: ''
  },
  loading: true,
  labels: [],
  currentLabel: null,
  emails: []
}

export const connect = () => {
  return (dispatch, getState) => {
    dispatch(turnLoadingOn())
    gmailAuth(false, populateCredentials(dispatch), clearCredentials(dispatch))
  }
}...
like image 393
Ycon Avatar asked Nov 15 '16 14:11

Ycon


Video Answer


1 Answers

I think you're right. The way I'm handling these situations is by loading the external JS file from React and using it in a promise.

So your flow should be something like this:

  1. React app loads
  2. React app injects your file in the HTML
  3. Do your thing in step 2's callback or .then()

Create a helper function. Put it in a folder like helpers/load-script. Below you have all the code you should have in that file:

export default function loadScript(url, cb) {

      var scr = document.createElement('script');
      scr.type = 'text/javascript';

      if (scr.readyState) { // IE
        scr.onreadystatechange = function() {
          if (scr.readyState ==`loaded' || scr.readyState ==='complete') {
            scr.onreadystatechange = null;
            cb();
          }
        };
      } else { // Others
        scr.onload = cb;
      }

      script.src = url;
      document.getElementsByTagName('head')[0].appendChild(scr);
    }

Next, import that function inside the component you want to use it into:

import React from 'react';
import loadScript from 'helpers/load-script';

class testComponent extends React.Component {
    
  componentDidMount() {
    loadScript('https://apis.google.com/js/client.js', () => {
    // do mail api stuff here               
    });
  }
   
  render() {
    return (
      <div>hi there</div>
    );
  }
}

export default testComponent;
like image 134
Tudor Leustean Avatar answered Oct 11 '22 02:10

Tudor Leustean