admin管理员组文章数量:1429558
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=".js"></script>
Index.js
import './Mail.js';
Mail.js
import { createAction, handleActions } from 'redux-actions'
const CLIENT_ID = '1.apps.googleusercontent'
const SCOPES = ['.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))
}
}...
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./js/client.js"></script>
Index.js
import './Mail.js';
Mail.js
import { createAction, handleActions } from 'redux-actions'
const CLIENT_ID = '1.apps.googleusercontent.'
const SCOPES = ['https://www.googleapis./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))
}
}...
Share
Improve this question
asked Nov 15, 2016 at 14:03
YconYcon
1,9506 gold badges32 silver badges56 bronze badges
1
- is your gmail-api script tag after your bundled react/application script tag? – Conan Commented Nov 15, 2016 at 15:09
2 Answers
Reset to default 6I 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:
- React app loads
- React app injects your file in the HTML
- 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 ==='plete') {
scr.onreadystatechange = null;
cb();
}
};
} else { // Others
scr.onload = cb;
}
script.src = url;
document.getElementsByTagName('head')[0].appendChild(scr);
}
Next, import that function inside the ponent you want to use it into:
import React from 'react';
import loadScript from 'helpers/load-script';
class testComponent extends React.Component {
ponentDidMount() {
loadScript('https://apis.google./js/client.js', () => {
// do mail api stuff here
});
}
render() {
return (
<div>hi there</div>
);
}
}
export default testComponent;
I had the same problem with GrowSurf Javascript Web API, The external script loaded after the render function, and its function was being undefined in ponentDidMount()
.
This is a logic I used to get the GrowSurf function not to be undefined. It can also help anyone who wants to use a function of any external JS introduced in index.html.
You can use DOMSubtreeModified
in ponentDidMount()
to check every time the DOM is modified, once the external JS is loaded(found) run your function there, and then stop the looping of DOMSubtreeModified
.
ponentDidMount() {
let functionDefined = false;
window.addEventListener('DOMSubtreeModified', function () {
if(!functionDefined) {
if (window.growsurf) {
console.log('a function is defined', window.growsurf.getReferrerId());
functionDefined = true;
}
}
}, false);
}
For your case, you can simply do this.
ponentDidMount() {
let functionDefined = false;
window.addEventListener('DOMSubtreeModified', function () {
if(!functionDefined) {
if (window.gapi) {
// do mail api stuff here
functionDefined = true;
}
}
}, false);
}
本文标签: javascriptReact only run file once external js file loaded (gapi not defined)Stack Overflow
版权声明:本文标题:javascript - React- only run file once external js file loaded (gapi not defined) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745525794a2661828.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论