How to implement Google APIs with React, Redux, and Webpack

I am trying to get google calendar events in a React Redux app.
I tried using googleapis and google-auth-library, but webpack throws errors because googleapis was created to run on the server side, and bundle.js refers to the client. Therefore, I read several forums about these errors, and all of them point to the use of the Google js client library .

I understand how to implement this in a java or php application (I'm old ... 35;), but I'm new to React Redux, and I'm looking for a better way to implement this.

I am trying to extract events from my calendar into my actions.js. I tried to include <script src="https://apis.google.com/js/api.js"></script> in my html header and then using gapi.load () from actions.js. I also tried creating an api.js file and referencing this with require ('./api'). I also tried using the cli commands from the Node.js Quickstart guide to get the access_token, and then just use axios to directly call the Google API but I get 403. I think I just do not provide the correct headers, but it still won’t be the best practice.

My question basically is, how can I reference the Google js client library from the actions.js file, adhering to Redux standards?

+5
source share
4 answers

I am going to answer my question, despite the very good correct answers. @MattYao answered my real question about how to get js script available for reference in actions.js file. @Ethan Brown gave a very detailed answer that showed excellent flow capabilities. @realseanp changed the scope, but a valid answer.

I tried all of the above and they worked.

So I'm not sure what I'm doing wrong, but I was finally able to access the gapi object from actions.js by simply adding <script src="https://apis.google.com/js/api.js"></script> into my index head. I use a pug to make it look like this:

 doctype html head title MyTitle link(rel='stylesheet' href='/static/css/main.css') link(rel='stylesheet' href='/static/css/react-big-calendar.css') script(src='https://apis.google.com/js/api.js' type='text/javascript') body div(id='app') script(src='/static/bundle.js' type='text/javascript') 

Here is my component file:

 import React from 'react' import BigCalendar from 'react-big-calendar'; import moment from 'moment'; import { connect } from 'react-redux' import { fetchEvents } from '../actions/actions' BigCalendar.momentLocalizer(moment); @connect((store) => { return { events: store.events.events } }) export default class Calendar extends React.Component { componentWillMount() { this.props.dispatch(fetchEvents()) } render() { return ( <div> <BigCalendar events={this.props.events} startAccessor='startDate' endAccessor='endDate' style={{height: 800}} /> </div> ) } } 

And then I was able to get this to work in the actions.js file

 export function fetchEvents() { return (dispatch) => { function start() { // 2. Initialize the JavaScript client library. gapi.client.init({ 'apiKey': API_KEY, // clientId and scope are optional if auth is not required. 'clientId': CLIENT_ID, 'scope': 'profile', }).then(function() { // 3. Initialize and make the API request. return gapi.client.request({ 'path': 'https://www.googleapis.com/calendar/v3/calendars/ MY_EMAIL@gmail.com /events?timeMax=2017-06-03T23:00:00Z&timeMin=2017-04-30T00:00:00Z', }) }).then( (response) => { let events = response.result.items dispatch({ type: 'FETCH_EVENTS_FULFILLED', payload: events }) }, function(reason) { console.log(reason); }); }; // 1. Load the JavaScript client library. gapi.load('client', start) }} 

I had to make my calendar open to access in this way. So, now I will work on oauth2 material: /

+1
source

Can you try this library that I used to load external libraries and modules into a React application when I could not find an NPM module for it:

https://github.com/ded/script.js/

So your code will be like this:

 import $script from 'scriptjs'; $script('https://apis.google.com/js/api.js', function () { //Put your google api functions here as callback }); 
+3
source

You are on the right track by including the official Google HTML client in your HTML header. That would not be ideal, it would be nice if Google provided an API (browser) as an npm module that you could import . But they don’t do it (I see), so I think you are doing well.

Then the question arises: "How can I use it so that React / Redux is friendly?" Redux is a mechanism for managing the state of your application. The Google API is not part of your application (although what you do with it may indicate the status of your application).

It’s easy to verify that you have access to the Google API: you can just call from the componentDidMount method of one of your components and make a console log:

 class MyComp extends React.Component { componentDidMount() { // this is taken directly from Google documentation: // https://developers.google.com/api-client-library/javascript/start/start-js function start() { // 2. Initialize the JavaScript client library. gapi.client.init({ 'apiKey': 'YOUR_API_KEY', // clientId and scope are optional if auth is not required. 'clientId': 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com', 'scope': 'profile', }).then(function() { // 3. Initialize and make the API request. return gapi.client.request({ 'path': 'https://people.googleapis.com/v1/people/me', }) }).then(function(response) { console.log(response.result); }, function(reason) { console.log('Error: ' + reason.result.error.message); }); }; // 1. Load the JavaScript client library. gapi.load('client', start); }, } 

If you do not see what you expect from the console, somehow gapi does not load as you expect. If this happens, you will have a more specific question that you can ask!

If you get the answer, you now know how to invoke GAPI ... but then, how to use it in a Redux-friendly way?

When you make a GAPI call, you probably want to somehow change the state of your application (otherwise, why are you doing this?) For example, you can call an authentication flow, and when the GAPI returns success, your application state now has loggedIn: true or similar (possibly with a lot of other state changes). Where you make the GAPI call is up to you. If you want to do this when the component loads, you must do this in componentDidMount . You can also usually make a GAPI call in response to a user action, such as clicking a button.

So a typical thread would be something like this:

 // either in componentDidMount, or a control handler, usually: someGapiCall() .then(result => { this.props.onGapiThing(result.whatever) }) 

Where this.props.onGapiThing is a function that dispatches an appropriate action that changes your application state.

I hope this review helps ... feel free to follow up on more specific issues.

+2
source

I uploaded all google content to my index file before I uploaded my webpack package ( Option 1 ). Then I used redux sagas to call google-apis. By downloading google code before the webpack package will guarantee that everything will be ready when you call the api from the saga

0
source

Source: https://habr.com/ru/post/1267343/


All Articles