method().bind(this) + Angular4 getting Cannot read property 'myFun' of undefined - javascript

I'm integrating Google picker API in my application. I'm following the official documentation Google Picker API
I have successfully done my job, but after adding below code I am unable to use class methods and variables. Getting Cannot read property of undefined error
gapi.load('auth', {'callback': this.onAuthApiLoad.bind(a)});
Complete code is:
onApiLoad() {
var a= this;
gapi.load('auth', {'callback': this.onAuthApiLoad.bind(a)});
gapi.load('picker');
}
onAuthApiLoad() {
gapi.auth.authorize(
{
'client_id': this.clientId,
'scope': this.scope,
'immediate': false
},
this.handleAuthResult);
}
handleAuthResult(authResult) {
if (authResult && !authResult.error) {
if (authResult.access_token) {
var pickerBuilder = new google.picker.PickerBuilder();
var picker = pickerBuilder.
enableFeature(google.picker.Feature.NAV_HIDDEN).
setOAuthToken(authResult.access_token).
addView(google.picker.ViewId.DOCS).
setCallback(this.myFun).
build();
picker.setVisible(true);
}
}
}
myFun(e){
}

I have added below line to handle auth request
this.handleAuthResult.bind(this)

Related

Google Picker API + Angular2 getting Failed to execute 'postMessage' on 'DOMWindow'

I am looking to integrate Google Picker API in my Angular 2 application.
My HTML Code:
<h1>
{{title}}
</h1>
<button (click)="onApiLoad()">Click Me!</button>
My Component Typescript Code:
import { Component } from '#angular/core';
declare var gapi:any;
declare var google:any;
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
developerKey = 'AIzaSyDFf3LoI2iGoq21Py5mx0YdRZC4-wOu2jQ';
clientId = "487432935414-ekonc03orunp50312oqmlrauutorpb53.apps.googleusercontent.com"
scope = ['https://www.googleapis.com/auth/drive.readonly'];
pickerApiLoaded = false;
oauthToken?: any;
constructor() { }
onApiLoad() {
gapi.load('auth', {'callback': this.onAuthApiLoad.bind(this)});
gapi.load('picker', {'callback': this.onPickerApiLoad.bind(this)});
}
onAuthApiLoad() {
gapi.auth.authorize(
{
'client_id': this.clientId,
'scope': this.scope,
'immediate': false
},
this.handleAuthResult);
}
onPickerApiLoad() {
this.pickerApiLoaded = true;
this.createPicker();
}
handleAuthResult(authResult) {
if (authResult && !authResult.error) {
if (authResult.access_token) {
var pickerBuilder = new google.picker.PickerBuilder();
var picker = pickerBuilder.
enableFeature(google.picker.Feature.NAV_HIDDEN).
setOAuthToken(authResult.access_token).
addView(google.picker.ViewId.PHOTOS).
setDeveloperKey('AIzaSyDFf3LoI2iGoq21Py5mx0YdRZC4-wOu2jQ').
setCallback(function (e){
var url = 'nothing';
console.log(url);
if (e[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = e[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
}
var message = 'You picked: ' + url;
console.log(message);
}).
build();
picker.setVisible(true);
}
}
}
createPicker() {
if (this.pickerApiLoaded && this.oauthToken) {
var picker = new google.picker.PickerBuilder().
addView(google.picker.ViewId.DOCUMENTS).
setOAuthToken(this.oauthToken).
setDeveloperKey(this.developerKey).
setCallback(this.pickerCallback).
build();
picker.setVisible(true);
}
}
pickerCallback(data) {
var url = 'nothing';
console.log(url);
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
}
var message = 'You picked: ' + url;
alert(message);
}
I am able to login to the google and getting access token, but after that I am unable to see documents in google drive.
Instead of that I am getting below errors:
cb=gapi.loaded_0:96 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://docs.google.com') does not match the recipient window's origin ('https://localhost:4200').
Invalid 'X-Frame-Options' header encountered when loading 'https://docs.google.com/picker?protocol=gadgets&origin=https%3A%2F%2Flocalhost%3A4200&navHidden=true&oauth_token=ya29.GlskBRj74kFwZFmKi3ecOvMG9yGYjoTnaaxpf84M_qSOwANu_m3uSvzciXupB35CXxHvfHgNQuS_pfVG9lwRnrKA4JQiU5mTX3hNEWxBQ69cJTMyTnn0LzsQJOgB&developerKey=AIzaSyDFf3LoI2iGoq21Py5mx0YdRZC4-wOu2jQ&hostId=localhost&relayUrl=https%3A%2F%2Flocalhost%3A4200%2Ffavicon.ico&nav=((%22photos%22))&rpctoken=vcwxj7g2b339&rpcService=sz95b67m0h97&thirdParty=true': 'ALLOW-FROM https://localhost:4200' is not a recognized directive. The header will be ignored.
Output:
It's a CORS issue. Your client_id credentials should have you localhost whitelisted in https://console.developers.google.com/
Go to credentials
Click on the client ids you are using under OAuth 2.0 Client IDs
Add you localhost under Authorized JavaScript Origins i.e
http://localhost:8601

Google Calendar API getting 'Cannot read property 'signIn' of null'

I'm trying to use Google's Calendar API to get info on specific calendar. I keep getting this error Cannot read property 'signIn' of null. I'm using the example online here https://developers.google.com/google-apps/calendar/quickstart/js.
Any idea why this is happening? And can someone give me a more simple way to get calendar data? Basically I want to know which rooms in my calendar feed are free to book. Can I do this using the calendar API?
const CLIENT_ID = '418414126140-u5u3r2ampke8egh7d2tk50ferkl8ri26.apps.googleusercontent.com';
const SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"];
app.factory('getCalendar', ['$q', function($q){
return function checkAuth() {
var deferred = $q.defer();
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
handleClientLoad();
function initClient() {
gapi.client.init({
"client_id": CLIENT_ID,
"scope": SCOPES
}).then(function () {
gapi.auth2.getAuthInstance().signIn();
});
}
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
console.log("You are authorized");
listUpcomingEvents();
} else {
console.log("You are not authorized");
}
}
function listUpcomingEvents() {
gapi.client.calendar.events.list({
'calendarId': 'primary',
'timeMin': (new Date()).toISOString(),
'showDeleted': false,
'singleEvents': true,
'maxResults': 10,
'orderBy': 'startTime'
}).then(function(response) {
console.log(response);
deferred.resolve(response);
});
}
return deferred.promise;
} //return ends here
}]);
Try using gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus); instead of gapi.auth2.getAuthInstance().signIn();. You may refer with this sample code on how to use the Google JavaScript Client API Library to authenticate and interact with the API.
Also check this related SO thread and see if it helps.
UPDATE:
Any idea on how to check which rooms on your calendar are available or not?
You may check on this link: Google Calendar Api, Is meeting Room available?
You will need to be authenticated as a user that has read-access to the room. Then you can take the resourceEmail field of the Calendar Resource API and use it as a calendarId in the events.list() Calendar API call.

Google Auth stopped working after 2 years

I've got the following code snippet:
// Google functions
var clientId = 'clientid';
var apiKey = 'apikey';
var scopes = 'https://www.googleapis.com/auth/calendar';
function handleClientLoad() {
// Step 2: Reference the API key
gapi.client.setApiKey(apiKey);
gapi.client.load('calendar', 'v3', function () {
window.setTimeout(checkAuth, 1);
});
}
function checkAuth() {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}
function handleAuthResult(authResult) {
console.error(authResult.error);
if (authResult && !authResult.error) {
if (!$('#authWait').is(':visible')) {
$('#start').on("click", function () {
$('#main').hide();
$('#wizard').removeClass("hidden");
});
} else {
$('#authWait').addClass("hidden");
$('#wizard').removeClass("hidden");
}
fillCalendarList();
ga('send', 'event', 'weergaveResultaat', 'action');
} else {
$('#start').on("click", function () {
$('#main').hide();
$('#authWait').removeClass("hidden");
handleAuthClick();
})
}
}
I've replaced the clientid and apikey. The exact snippet above has been working for 2 years in the exact same configuration. As of yesterday however I'm getting back 'immediate failed' right after the handleAuthResult.
I couldn't find any details of changes Google made since yesterday. I've tried switching immediate to false, but that didn't solve anything.
After the immediate failed I get 'Uncaught TypeError: Cannot set property 'apiVersion' of undefined'.
Anyone know what is causing this?

Google drive Public

I am working with Google drive picker, where once an item is selected from Google drive a url is produced. The problem is that that url is only accessible by the owner, and hence not public. I want the URL to be publicly accessible.
Hence, i've looked into the following guide:
https://developers.google.com/picker/docs/reference#Response.Documents
and feel that the Document.AUDIENCE class would be best applicable, however I do not know how to add that criteria into the below google drive picker example code.
Any help would be greatly appreciated.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Picker Example</title>
<script type="text/javascript">
// The Browser API key obtained from the Google Developers Console.
var developerKey = 'xxxxxxxYYYYYYYY-12345678';
// The Client ID obtained from the Google Developers Console. Replace with your own Client ID.
var clientId = "1234567890-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com"
// Scope to use to access user's photos.
var scope = ['https://www.googleapis.com/auth/photos'];
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': false
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for picking user Photos.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var picker = new google.picker.PickerBuilder().
addView(google.picker.ViewId.PHOTOS).
setOAuthToken(oauthToken).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
var url = 'nothing';
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
url = doc[google.picker.Document.URL];
}
var message = 'You picked: ' + url;
document.getElementById('result').innerHTML = message;
}
</script>
</head>
<body>
<div id="result"></div>
<!-- The Google API Loader script. -->
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
</body>
To add public permissions to the selected file. You will need to use the drive api to add file permissions
Please see https://developers.google.com/drive/v2/reference/permissions/insert
You will need to insert a permission to the file with role set to 'reader' and the type to 'anyone'
You can refer to the javascript implementation in the example
/**
* Insert a new permission.
*
* #param {String} fileId ID of the file to insert permission for.
* #param {String} value User or group e-mail address, domain name or
* {#code null} "default" type.
* #param {String} type The value "user", "group", "domain" or "default".
* #param {String} role The value "owner", "writer" or "reader".
*/
function insertPermission(fileId, value, type, role) {
var body = {
'value': value,
'type': type,
'role': role
};
var request = gapi.client.drive.permissions.insert({
'fileId': fileId,
'resource': body
});
request.execute(function(resp) { });
}
To elaborate on #Sam's answer, here is how you would do it without using the gapi.client.drive Javascript API.
Let's say that some_id is your document id:
request = gapi.client.request({
path: '/drive/v2/files/some_id/permissions',
method: 'POST',
body: {
role: 'reader'
type: 'anyone'
}
});
request.execute(function (res) {
console.log(res);
})
Which generates a request to https://content.googleapis.com/drive/v2/files/some_id/permissions?alt=json with this body: {role: "reader", type: "anyone"}
Here is the result you will get:
{
"kind": "drive#permission",
"etag": "some etage",
"id": "anyone",
"selfLink": "https://www.googleapis.com/drive/v2/files/some_id/permissions/anyone",
"role": "reader",
"type": "anyone"
}

insufficient permission error due t scope

I encounter the following error in console while trying to execute my code:
POST https://content.googleapis.com/urlshortener/v1/url?alt=json&key=AIzaSyB3BGJskI7cJUvnl7jzjiX4eh86K9sldgA 403 (Forbidden)
I am using google URL Shortner API, and feel that the issue is derived from insufficient permission as shown by the error in details:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "insufficientPermissions",
"message": "Insufficient Permission"
}
],
"code": 403,
"message": "Insufficient Permission"
}
}
Below is the part of the code that I think affects it:
/ The Browser API key obtained from the Google Developers Console.
var developerKey = 'ID';
// The Client ID obtained from the Google Developers Console.
var clientId = 'ID';
// Scope to use to access user's photos.
var scope = ['https://www.googleapis.com/auth/drive'];
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': true
},
handleAuthResult);
}
In particular,
'scope': scope,
I have been struggling with this issue for a while and is looking for a soluton.

Categories

Resources