无法读取属性' loadGmailApi' unfine Angular2和Gmail API

时间:2016-11-13 19:40:16

标签: angular gmail gmail-api

我尝试使用Google Gmail API通过Gmail连接为Angular2创建组件。我需要一个来自我的Angular2应用程序的Gmail电子邮件列表,但我总是遇到同样的问题(zone.js:140 Uncaught TypeError:无法读取属性' loadGmailApi' of undefined(...))和我不明白这个错误的原因。

我理解下面的代码: 点击#authorize-button 按钮调用方法: handleAuthClick ,此方法可以正常工作。 上面的方法调用 this.handleAuthResult ,这部分代码也可以正常工作,但是当它调用 this.loadGmailApi 时,我收到错误:

zone.js:140 Uncaught TypeError: Cannot read property 'loadGmailApi' of undefined(…)

为什么我无法在this.handleAuthResult方法中调用this.loadGmailApi?

我的HTML代码:

<div id="authorize-div">
    <span>Authorize access to Gmail API</span>
    <!--Button for the user to click to initiate auth sequence -->
    <button id="authorize-button" (click)="handleAuthClick(event)">
        Authorize
    </button>
</div>
<pre id="output"></pre>

和TS文件:

import {Component, OnInit} from '@angular/core';
import {Router} from "@angular/router";


@Component({
    selector: 'gmail-app',
    templateUrl: '/app/gmail/gmail.component.html'
})

export class GmailComponent implements OnInit{
    // Your Client ID can be retrieved from your project in the Google
    // Developer Console, https://console.developers.google.com
    public CLIENT_ID:string = 'GOOGLE_API_ID_STRING.apps.googleusercontent.com';
    public SCOPES:Array<string> = ['https://www.googleapis.com/auth/gmail.readonly'];

    constructor(){
    }

    ngOnInit(){
    }

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

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

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

        /**
         * Load Gmail API client library. List labels once client library
         * is loaded.
         */

    loadGmailApi() {
        console.log("loadGmailApi");
        gapi.client.load('gmail', 'v1', this.listLabels);
    }

        /**
         * Print all Labels in the authorized user's inbox. If no labels
         * are found an appropriate message is printed.
         */
    listLabels() {
        console.log("listLabels");
        var request = gapi.client.gmail.users.labels.list({
            'userId': 'me'
        });

        request.execute(function(resp) {
            var labels = resp.labels;
            this.appendPre('Labels:');

            if (labels && labels.length > 0) {
                // for (private i = 0; i < labels.length; i++) {
                //     var label = labels[i];
                //     this.appendPre(label.name)
                // }
                this.appendPre('Labels foudnd - Kris disabled it');
            } else {
                this.appendPre('No Labels found.');
            }
        });
    }

        /**
         * 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) {
        console.log("appendPre");
        var pre = document.getElementById('output');
        var textContent = document.createTextNode(message + '\n');
        pre.appendChild(textContent);
    }
}

2 个答案:

答案 0 :(得分:0)

您无法在this函数中使用handleAuthResult,因为它具有不同的上下文。您可以在此处查看更多相关信息:How to access the correct `this` context inside a callback?

答案 1 :(得分:0)

感谢@Dralac的帮助和对How to access the correct this / context inside a callback?

的参考

如果有人遇到类似问题,我建议您观看此视频:Understanding this in TypeScript

最后,我在Angular2 TS服务中使用此引用创建了专用的GmailApiService:

import {Injectable} from "@angular/core";

@Injectable()
export class GmailApiService {
    public CLIENT_ID = '525210254723-5a80ara29lspplau6khbttb0fbacnppr.apps.googleusercontent.com';
    public SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];

    checkAuthAuto = () => {
        gapi.auth.authorize(
            {
                'client_id': this.CLIENT_ID,
                'scope': this.SCOPES.join(' '),
                'immediate': true
            }, this.handleAuthResult);
    };

    checkAuthManual = () => {
        gapi.auth.authorize(
            {
                'client_id': this.CLIENT_ID,
                'scope': this.SCOPES.join(' '),
                'immediate': false
            }, this.handleAuthResult);
        return false;
    };


    handleAuthResult = (authResult) => {
        var authorizeDiv = document.getElementById('authorize-div');

        if (authResult && !authResult.error) {
            // Hide auth UI, then load client library.
            authorizeDiv.style.display = 'none';
            this.loadGmailApi();
        } else {
            // Show auth UI, allowing the user to initiate authorization by
            // clicking authorize button.
            authorizeDiv.style.display = 'inline';
        }
    };

    loadGmailApi = () => {
        gapi.client.load('gmail', 'v1', this.listLabels);
    };

    listLabels = () => {
        var request = gapi.client.gmail.users.labels.list({
            'userId': 'me'
        });
        var self = this;

        request.execute(function(resp) {
            var labels = resp.labels;
            self.appendPre('Labels:');

            if (labels && labels.length > 0) {
                for (var i = 0; i < labels.length; i++) {
                    var label = labels[i];
                    self.appendPre(label.name)
                }
            } else {
                self.appendPre('No Labels found.');
            }
        });
    };

    appendPre = (message) => {
        var pre = document.getElementById('output');
        var textContent = document.createTextNode(message + '\n');
        pre.appendChild(textContent);
    }
}