Search code examples
reactjstypescriptgoogle-api-js-client

Property 'calendar' does not exist on type 'typeof client'


I'm trying to connect my Google Calender to my React website. I've got a component called Calendar. I've used the JS tutorial from Google and I've changed it to work in Typescript. I've got the authentication and authorization already working, however fetching data from the calendar is not working. I'm getting the following error when compiling/editing.

[ts] Property 'calendar' does not exist on type 'typeof client'. Did you mean 'calendars'?

I've already downloaded the types for the gapi.client.calendar and as you can see in the image below, they are also found in the @types folder. I'm kind of stuck and I don't know how I can fix this issue..

@Types folder

Here is my code from my Calendar.tsx

import * as React from 'react';
import { Button } from 'semantic-ui-react'
import googleApiKey from '../googleapi-key.json';

const CLIENT_ID = googleApiKey.CLIENT_ID;
const API_KEY = googleApiKey.API_KEY;
const DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];
const SCOPES = "https://www.googleapis.com/auth/calendar.readonly";


class Calendar extends React.Component {
    constructor(props: any) {
        super(props);

        console.log(CLIENT_ID);
        console.log(API_KEY);

        this.handleClientLoad = this.handleClientLoad.bind(this);
        this.handleAuthClick = this.handleAuthClick.bind(this);
        this.handleSignoutClick = this.handleSignoutClick.bind(this);
        this.initClient = this.initClient.bind(this);
        this.updateSigninStatus = this.updateSigninStatus.bind(this);
        this.listUpcomingEvents = this.listUpcomingEvents.bind(this);
    }

    componentDidMount() {
        this.initClient();
    }


    public render() {
        return (
            <div>
                <Button onClick={this.handleAuthClick}>
                    authorizeButton
                </Button>

                <Button onClick={this.handleSignoutClick}>
                    signoutButton
                </Button>
            </div>
        );
    }

    /**
     *  On load, called to load the auth2 library and API client library.
     */
    public handleClientLoad() {
        gapi.load('client:auth2', this.initClient);
    }

    /**
 *  Sign in the user upon button click.
 */
    public handleAuthClick(event: any) {
        gapi.auth2.getAuthInstance().signIn();
    }

    /**
     *  Sign out the user upon button click.
     */
    public handleSignoutClick(event: any) {
        gapi.auth2.getAuthInstance().signOut();
    }

    /**
     *  Initializes the API client library and sets up sign-in state
     *  listeners.
     */
    public async initClient() {
        await gapi.client.init({
            apiKey: API_KEY,
            clientId: CLIENT_ID,
            discoveryDocs: DISCOVERY_DOCS,
            scope: SCOPES
        })

        // Listen for sign-in state changes.
        gapi.auth2.getAuthInstance().isSignedIn.listen(this.updateSigninStatus);

        // Handle the initial sign-in state.
        this.updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());

    }

    /**
     *  Called when the signed in status changes, to update the UI
     *  appropriately. After a sign-in, the API is called.
     */
    public updateSigninStatus(isSignedIn: any) {
        if (isSignedIn) {
            this.listUpcomingEvents();
        }
    }

    /**
     * Print the summary and start datetime/date of the next ten events in
     * the authorized user's calendar. If no events are found an
     * appropriate message is printed.
     */
    public listUpcomingEvents() {
        console.log(gapi.client.calendar); // <--- Compile error: Does not recognize calendar
    }
}

export default Calendar;

EDIT

When performing console.log(gapi.client) I can see that the client contains a calendar object (see image). But why can't I reach it in my own code?

console.log(gapi.client)


Solution

  • I managed to fix my own problem. After performing console.log(gapi.client) I noticed that calender was already there, so I tried the following gapi.client['calendar'] and it worked as it should. I don't know why Typescript does not recognize the calendar in the first place, so if anybody has an idea feel free to leave a comment.