2016-10-18 2 views
1

내 웹 앱에 Google 스프레드 시트 API를 포함 시키려고하지만 gapi 라이브러리가 정의되지 않았다는 오류 메시지가 계속 나타납니다. 나는 ComponentDidMount 라이프 사이클 메소드를 사용하여 서버에 대한 요청을 지연시키고, 그 메소드에서 타임 아웃을 사용해도 시도했지만, 같은 에러를 계속 받는다. 내 응용 프로그램에서 사용하기 위해 gapi 라이브러리를 어떻게 정의 할 수 있습니까?GAPI가 정의되지 않았습니다 - ReactJS - Google 스프레드 시트

import React from 'react'; 
var CLIENT_ID = ''; 
var SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"]; 


export default class MyNavbar extends React.Component { 

    constructor(props) { 
    super(props); 
    } 

    componentDidMount(){ 
    this.checkAuth(); 

    } 

     /** 
     * Check if current user has authorized this application. 
     */  
    checkAuth(){ 
     gapi.auth.authorize(
      { 
      'client_id': CLIENT_ID, 
      'scope': SCOPES.join(' '), 
      'immediate': true 
      }, this.handleAuthResult()); 
     } 

     /** 
     * Handle response from authorization server. 
     * 
     * @param {Object} authResult Authorization result. 
     */ 
     handleAuthResult(authResult) { 
     var authorizeDiv = document.getElementById('authorize-div'); 
     if (authResult && !authResult.error) { 
      // Hide auth UI, then load client library. 
      authorizeDiv.style.display = 'none'; 
      loadSheetsApi(); 
     } else { 
      // Show auth UI, allowing the user to initiate authorization by 
      // clicking authorize button. 
      authorizeDiv.style.display = 'inline'; 
     } 
     } 

     /** 
     * Initiate auth flow in response to user clicking authorize button. 
     * 
     * @param {Event} event Button click event. 
     */ 
    handleAuthClick(event) { 
     gapi.auth.authorize(
      {client_id: CLIENT_ID, scope: SCOPES, immediate: false}, 
      handleAuthResult); 
     return false; 
     } 

     /** 
     * Load Sheets API client library. 
     */ 
    loadSheetsApi() { 
     var discoveryUrl = 
      'https://sheets.googleapis.com/$discovery/rest?version=v4'; 
     gapi.client.load(discoveryUrl).then(listMajors); 
     } 

     /** 
     * Print the names and majors of students in a sample spreadsheet: 
     * https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit 
     */ 
     listMajors() { 
     gapi.client.sheets.spreadsheets.values.get({ 
      spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms', 
      range: 'Class Data!A2:E', 
     }).then(function(response) { 
      var range = response.result; 
      if (range.values.length > 0) { 
      appendPre('Name, Major:'); 
      for (i = 0; i < range.values.length; i++) { 
       var row = range.values[i]; 
       // Print columns A and E, which correspond to indices 0 and 4. 
       appendPre(row[0] + ', ' + row[4]); 
      } 
      } else { 
      appendPre('No data found.'); 
      } 
     }, function(response) { 
      appendPre('Error: ' + response.result.error.message); 
     }); 
     } 

     /** 
     * Append a pre element to the body containing the given message 
     * as its text node. 
     * 
     * @param {string} message Text to be placed in pre element. 
     */ 
     appendPre(message) { 
     var pre = document.getElementById('output'); 
     var textContent = document.createTextNode(message + '\n'); 
     pre.appendChild(textContent); 
     } 


    render(){ 
     return (
     <div> 
      <h1>Hello World My Name Is Justin 2</h1> 
      <div id="authorize-div"></div> 
      <pre id="output"></pre> 
     </div> 
    ); 
    } 
} 
+0

지연 당신이 GAPI 라이브러리를로드 할 필요가 도움이되지 않습니다. 전체 파일을 게시 할 수 있습니까? – sylvain

답변

0

당신은 index.html을 파일에 bundle.js 전에 gapi 라이브러리를로드 할 필요가, 또는 더 나은 당신은 와 비동기 gapi JS 스크립트를로드 할 수있는 반응 - 비동기 로더을. 다음은 그것을 할 수있는 방법은 다음과 같습니다

import React, { Component, PropTypes } from 'react'; 
import asyncLoad from 'react-async-loader'; // for loading script tag asyncly 

// For making gapi object passed as props to our component 
const mapScriptToProps = state => ({ 
    gapi: { 
    globalPath: 'gapi', 
    url: 'https://your-gapi-url' 
    } 
}); 
// decorate our component 
@asyncLoad(mapScriptToProps) 
class yourComponent extends Component { 
    componentDidMount() { 
     // Check is gapi loaded? 
     if (this.props.gapi !== null) { 
     this.checkAuth(); 
     } 
    } 

    componentWillReceiveProps({ gapi }) { 
     if (gapi!== null) { 
     this.checkAuth(); 
     } 
    } 

    checkAuth =() => { 
     // Better check with window and make it available in component 
     this.gapi = window.gapi; 
     this.gapi.auth.authorize({ 
     'client_id': CLIENT_ID, 
     'scope': SCOPES.join(' '), 
     'immediate': true 
     }, this.handleAuthResult); 
    } 

    handleAuthResult = (authData) => { 
     // Your auth loagic... 
    } 

    render() { 
     return (<div> 
        { this.props.gapi && 
        <YourSpreadsheetOrWhatever data={ this.getData() } /> 
        } 
      </div>) 
    } 
} 

보십시오이 당신의 코드를 교체하고 작동하는지 확인합니다.

+0

여전히 오류가 발생하여 내 사례를 업데이트하려고합니다. –

+0

어떤 오류가 발생합니까? 오류를 보여줄 수 있습니까? –

0

여기를 시도해보십시오.

import React from 'react'; 
import asyncLoad from 'react-async-loader'; // for loading script tag asyncly `npm i --save react-async-loader` 

const CLIENT_ID = ''; 
const SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"]; 

// For making gapi object passed as props to our component 
const mapScriptToProps = state => ({ 
    // gapi will be this.props.gapi 
    gapi: { 
     globalPath: 'gapi', 
     url: 'https://your-gapi-url' 
    } 
}); 

@asyncLoad(mapScriptToProps) 
class MyNavbar extends React.Component { 

    constructor(props) { 
    super(props); 
    this.gapi = null; 
    // You need to bind methods to this class's object context. (i.e this)! 
    this.checkAuth = this.checkAuth.bind(this); 
    this.handleAuthResult = this.authResult.bind(this); 
    this.handleAuthClick = this.handleAuthClick.bind(this); 
    this.loadSheetsApi = this.loadSheetsApi.bind(this); 
    this.listMajors = this.listMajors.bind(this); 
    } 

    componentDidMount() { 
    // Check is gapi loaded? 
    if (this.props.gapi !== null) { 
     this.checkAuth(); 
    } 
    } 

    componentWillReceiveProps({ gapi }) { 
    if (gapi!== null) { 
     this.checkAuth(); 
    } 
    } 

    /** 
    * Check if current user has authorized this application. 
    */ 
    checkAuth() { 

    // this will give you an error of gapi is not defined because there is no 
    // reference of gapi found globally you cannot access global object which are 
    // not predefined in javascript(in this case its window.gapi). 
    // properties added by Programmer cannot be accessed directly(if it's not in the same file as well as the same scope!) in commonjs modules. Because they 
    // don't' run in a global scope. Any variable in another module which is not 
    // exported, will not be available to other modules. 

    this.gapi = window.gapi; // you can do like this. Now you can access gapi in all methods if this class. 
    this 
     .gapi 
     .auth 
     .authorize({ 
      'client_id': CLIENT_ID, 
      'scope': SCOPES.join(' '), 
      'immediate': true 
     }, this.handleAuthResult()); 
    } 

    /** 
    * Handle response from authorization server. 
    * 
    * @param {Object} authResult Authorization result. 
    */ 
    handleAuthResult(authResult) { 
    var authorizeDiv = document.getElementById('authorize-div'); 
    if (authResult && !authResult.error) { 
     // Hide auth UI, then load client library. 
     authorizeDiv.style.display = 'none'; 
     loadSheetsApi(); 
    } else { 
     // Show auth UI, allowing the user to initiate authorization by clicking 
     // authorize button. 
     authorizeDiv.style.display = 'inline'; 
    } 
    } 

    /** 
    * Initiate auth flow in response to user clicking authorize button. 
    * 
    * @param {Event} event Button click event. 
    */ 
    handleAuthClick(event) { 
    // gapi.auth.authorize( here also gapi is not defined 
    this 
     .gapi 
     .auth 
     .authorize({ 
      client_id: CLIENT_ID, 
      scope: SCOPES, 
      immediate: false 
     }, handleAuthResult); 
    return false; 
    } 

    /** 
    * Load Sheets API client library. 
    */ 
    loadSheetsApi() { 
    var discoveryUrl = 'https://sheets.googleapis.com/$discovery/rest?version=v4'; 
    // also will give your error 
    // for gapi being not defined. 
    // gapi.client.load(discoveryUrl).then(listMajors); 
    this 
     .gapi 
     .client 
     .load(discoveryUrl) 
     .then(listMajors); 
    } 

    /** 
    * Print the names and majors of students in a sample spreadsheet: 
    * https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit 
    */ 
    listMajors() { 
    this.gapi 
     .client 
     .sheets 
     .spreadsheets 
     .values 
     .get({spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms', range: 'Class Data!A2:E'}) 
     .then(function (response) { 
      var range = response.result; 
      if (range.values.length > 0) { 
       appendPre('Name, Major:'); 
       for (i = 0; i < range.values.length; i++) { 
        var row = range.values[i]; 
        // Print columns A and E, which correspond to indices 0 and 4. 
        appendPre(row[0] + ', ' + row[4]); 
       } 
      } else { 
       appendPre('No data found.'); 
      } 
     }, function (response) { 
      appendPre('Error: ' + response.result.error.message); 
     }); 
    } 

/** 
    * Append a pre element to the body containing the given message 
    * as its text node. 
    * 
    * @param {string} message Text to be placed in pre element. 
    */ 
    appendPre(message) { 
    // as you can see. You are accessing window.document as document. 
    // its fine because its defined in javascript (implicitly), 
    // not explicitly by programmer(here you!). 
    var pre = document.getElementById('output'); 
    var textContent = document.createTextNode(message + '\n'); 
    pre.appendChild(textContent); 
    } 

    render() { 
    return (
     <div> 
      <h1>Hello World My Name Is Justin 2</h1> 
      <div id="authorize-div"></div> 
      <pre id="output"></pre> 
     </div> 
    ); 
    } 
} 

export default MyNavbar; 
0

이 프로젝트는 https://github.com/rlancer/gapi-starter입니다. 도움이 될 수 있습니다.

구글 로그인 & API + ReactJS + 흐름 + 웹팩 스타터 키트

구글 API 년대 좋지만 자바 스크립트 프로그래밍의 모듈 파트너가 인기가 전에 설계되었다. 이 초보자가 Google 로그인 및 라이브러리로드를 처리하도록 수정합니다.

코드 받기!

자식 클론 https://github.com/rlancer/gapi-starter.git CD GAPI - 스타터 NPM 설치