How to Integrate Google Calendar API with React JS?

Sivadass N picture Sivadass N · Jul 22, 2017 · Viewed 15.3k times · Source

I am trying to implement this vanilla js example of google calendar api in a react js app. The vanilla JS example works just fine in my local machine. But am getting lot of troubles when implementing the same in react. Please check my code below:

class App extends React.Component{
  constructor(props) {
    super(props);
    var CLIENT_ID = '992549188018-3prg54pp18je3e3qhgcttgl11491c4dm.apps.googleusercontent.com';
    var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];
    var SCOPES = "https://www.googleapis.com/auth/calendar";
    this.state = {
      showAuthButton: false,
      showSignOutButton: false
    };
    this.initClient = this.initClient.bind(this);
    this.updateSigninStatus = this.updateSigninStatus.bind(this);
  }
  handleAuthClick(){
    gapi.auth2.getAuthInstance().signIn();
  }
  handleSignoutClick(){
    gapi.auth2.getAuthInstance().signOut();
  }
  handleClientLoad() {
    gapi.load('client:auth2', this.initClient);
  }
  initClient(DISCOVERY_DOCS, CLIENT_ID, SCOPES) {
    gapi.client.init({
      discoveryDocs: DISCOVERY_DOCS,
      clientId: CLIENT_ID,
      scope: SCOPES
    }).then(function () {
      console.log(window.gapi);
      // Listen for sign-in state changes.
      window.gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

      // Handle the initial sign-in state.
      updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
      authorizeButton.onclick = handleAuthClick;
      signoutButton.onclick = handleSignoutClick;
    });
  }
  updateSigninStatus(isSignedIn) {
    if (isSignedIn) {
      this.setState({
        showAuthButton: false,
        showSignOutButton: true
      })
      //listUpcomingEvents();
      //insertNewEvent();
    } else {
      this.setState({
        showAuthButton: true,
        showSignOutButton: false
      })
    }
  }
  componentDidMount(){
    this.handleClientLoad();
  }
  render(){
    let authButton = <button id="authorize-button" onClick={this.handleAuthClick.bind(this)}>Authorize</button>
    let signOutButton = <button id="signout-button" onClick={this.handleSignoutClick.bind(this)}>Sign Out</button>
    return(
      <div className="container">
        {this.state.showAuthButton ? authButton : null}
        {this.state.showSignOutButton ? signOutButton : null}
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

Am getting this error as of now:

Uncaught TypeError: Cannot read property 'isSignedIn' of null

Please guide me to move further...

Answer

Sivadass N picture Sivadass N · Mar 10, 2018

Finally adding my solution which worked to help future comers :)

To get the list of events, authorization is not required. So removed the unnecessary code from google's quickstart example.

componentDidMount = () => {
  this.getEvents();
}

getEvents(){
  let that = this;
  function start() {
    gapi.client.init({
      'apiKey': GOOGLE_API_KEY
    }).then(function() {
      return gapi.client.request({
        'path': `https://www.googleapis.com/calendar/v3/calendars/${CALENDAR_ID}/events`,
      })
    }).then( (response) => {
      let events = response.result.items
      that.setState({
        events
      }, ()=>{
        console.log(that.state.events);
      })
    }, function(reason) {
      console.log(reason);
    });
  }
  gapi.load('client', start)
}

You can find the full code and functional demo here.