我尝试使用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);
}
}
答案 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);
}
}