XMLHttpRequest error for the Viewer - autodesk-forge

I use the following HTML file to test the Headless Viewer of Autodesk Forge. The test url will look like:
http://localhost:8080/HeadlessViewer.html?token={{Bearer}}&urn={{base64URN}}
The token has scope=data:read, urn is base64 format.
<html>
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />
</head>
<body>
<div id="MyViewerDiv"></div>
<!-- The Viewer JS -->
<script src="https://developer.api.autodesk.com/viewingservice/v1/viewers/three.min.js?v=v2.10.*"></script>
<script src="https://developer.api.autodesk.com/viewingservice/v1/viewers/viewer3D.js?v=v2.10.*"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<!-- Developer JS -->
<script>
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
function initViewer(token, urn) {
var viewerApp;
var options = {
env: 'AutodeskProduction',
accessToken: token
};
var documentId = atob(urn); // 'urn:<YOUR_URN_ID>';
Autodesk.Viewing.Initializer(options, onInitialized);
function onInitialized() {
viewerApp = new Autodesk.Viewing.ViewingApplication('MyViewerDiv');
viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Viewer3D);
viewerApp.loadDocument(documentId, onDocumentLoaded);
}
function onDocumentLoaded(lmvDoc) {
var modelNodes = viewerApp.bubble.search(av.BubbleNode.MODEL_NODE); // 3D designs
var sheetNodes = viewerApp.bubble.search(av.BubbleNode.SHEET_NODE); // 2D designs
var allNodes = modelNodes.concat(sheetNodes);
if (allNodes.length) {
viewerApp.selectItem(allNodes[0].data);
if (allNodes.length === 1) {
alert('This tutorial works best with documents with more than one viewable!');
}
} else {
alert('There are no viewables for the provided URN!');
}
}
}
$(document).ready(function () {
var url = window.location.href,
token = getParameterByName('token', url),
urn = getParameterByName('urn', url);
initViewer(token, urn);
});
</script>
</body>
</html>
However, it stops at the exception XMLHttpRequest.responseText. Please see the attached image: Error image

I tried your code just replacing the "accessToken: <>" and "var documentId = <>" and worked fine. Looking at your code, I believe the problem may be at the following line:
var documentId = atob(urn); // 'urn:<YOUR_URN_ID>';
The atob function will decode the string, which means it will not be on Base64. But the documentId should be like:
var documentId = 'urn:c29tZSByYW5kb20gd29yZHMgaGVyZQ==';
Please make sure the documentId is properly formed.
Finally, note the Viewer requires URL Safe encoding. Consider encoding on server (safer to transmit) or doing it on client-side, see this answer.

Related

Drive file picker from the older Google Sign-In platform library to the newer Google Identity Services library for authentication

I have a code where I read the file data as blob. I have implemented using the old gapi, how do I migrate from the older Google Sign-In platform library to the newer Google Identity Services library for authentication.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Google Picker Example</title>
</head>
<body>
<button id="authorize_button" style="display: none;">Authorize</button>
<button id="signout_button" style="display: none;">Sign Out</button>
<div id="result"></div>
<script type="text/javascript" src="script.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
<script>
const API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const CLIENT_ID = '995979103146-6qdmadbu7ha5ptrthsg8uqonkpplvc8e.apps.googleusercontent.com';
const appId = "995979103146";
const SCOPES = ["https://www.googleapis.com/auth/drive"];
const DISCOVERY_DOCS = [
"https://www.googleapis.com/discovery/v1/apis/drive/v3/rest",
];
const authorizeButton = document.getElementById("authorize_button");
const signoutButton = document.getElementById("signout_button");
// Use the Google API Loader script to load the google.picker script.
function handleClientLoad() {
gapi.load("client:auth2:picker", initClient);
}
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES[0]
})
.then(
function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(handleSignIn);
// Handle the initial sign-in state.
handleSignIn(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
},
function (error) {
appendPre(JSON.stringify(error, null, 2));
}
);
}
function handleSignIn(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = "none";
signoutButton.style.display = "block";
createPicker();
} else {
authorizeButton.style.display = "block";
signoutButton.style.display = "none";
}
}
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
function createPicker() {
const token = gapi.client.getToken().access_token
if (token) {
let view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes("image/png,image/jpeg,image/jpg");
let picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.setOAuthToken(token)
.addView(view)
.addView(new google.picker.DocsUploadView())
.setDeveloperKey(API_KEY)
.setCallback(getFile)
.build();
picker.setVisible(true);
}
}
function getFile(pickerResp) {
console.log(JSON.stringify(pickerResp))
if(pickerResp.action == "picked") {
gapi.client.drive.files
.get({
fileId: pickerResp.docs[0].id,
alt: 'media'
})
.then(resp => {
console.log("fetch response", resp.status)
let binary = resp.body
// EDIT - addition from Gabrielle vvvv
let l = binary.length
let array = new Uint8Array(l);
for (var i = 0; i<l; i++){
array[i] = binary.charCodeAt(i);
}
let blob = new Blob([array], {type: 'application/octet-stream'});
console.log(blob)
// EDIT - addition from Gabrielle ^^^^
});
}
}
</script>
</body>
</html>
It is really easy to implement the new Google Identity Library. As you can compare here, you only have to change a few things.
This example is the easiest approach (implicit flow):
One button for retrieving the token
One button for loading the picker
<html>
<body>
<script
src="https://accounts.google.com/gsi/client"
onload="initClient()"
async
defer
></script>
<script>
var client;
var access_token;
function loadPicker() {
gapi.load('picker', {'callback': ()=>console.log("Picker Loaded")});
}
function initClient() {
client = google.accounts.oauth2.initTokenClient({
client_id: "<CLIENT_ID>",
scope:
"https://www.googleapis.com/auth/drive.file",
callback: (tokenResponse) => {
access_token = tokenResponse.access_token;
},
});
}
function getToken() {
client.requestAccessToken();
}
function revokeToken() {
google.accounts.oauth2.revoke(access_token, () => {console.log('access token revoked')});
}
function onPickerApiLoad() {
var picker = new google.picker.PickerBuilder()
.addView(google.picker.ViewId.DOCS)
.setOAuthToken(access_token)
.build();
picker.setVisible(true);
}
</script>
<!-- The Google API Loader script. -->
<h1>Google Identity Services Authorization Token model</h1>
<button onclick="getToken();">Get access token</button><br /><br />
<button onclick="onPickerApiLoad()">Load picker</button>
<script src="https://apis.google.com/js/api.js?onload=loadPicker"></script>
</body>
</html>
Documentation:
Migrate to Google Identity Services
Google has released a new Code sample I would start there to see the changes for authorizaotn. It should just be a matter of swapping out the authorization methods. The rest of the code is unchanged.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Google Picker Example</title>
<script type="text/javascript">
// The Browser API key obtained from the Google API Console.
// Replace with your own Browser API key, or your own key.
var developerKey = 'xxxxxxxYYYYYYYY-12345678';
// The Client ID obtained from the Google API Console. Replace with your own Client ID.
var clientId = "1234567890-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com"
// Replace with your own project number from console.developers.google.com.
// See "Project number" under "IAM & Admin" > "Settings"
var appId = "1234567890";
// Scope to use to access user's Drive items.
var scope = ['https://www.googleapis.com/auth/drive.file'];
var pickerApiLoaded = false;
var oauthToken;
// Use the Google API Loader script to load the google.picker script.
function loadPicker() {
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 searching images.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes("image/png,image/jpeg,image/jpg");
var picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.setOAuthToken(oauthToken)
.addView(view)
.addView(new google.picker.DocsUploadView())
.setDeveloperKey(developerKey)
.setCallback(pickerCallback)
.build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
if (data.action == google.picker.Action.PICKED) {
var fileId = data.docs[0].id;
alert('The user selected: ' + fileId);
}
}
</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=loadPicker"></script>
</body>
</html>

How can i make the HTML file open in Chrome while the calling browser is Explorer

I have this HTML (attached).
It is called by a web app that still works on I.E (for at least one or two months) due to some problems we have with the vendor.
The web app calls this HTML and it is opened in I.E also.
I need this HTML to be opened in Chrome.
Is there a way i can do this by adding something to the HTML itself?
<html>
<head>
<script>
async function setSRC(){
try{
var xhr;
const params = new Proxy(new URLSearchParams(window.location.search),
{
get: (searchParams, prop) => searchParams.get(prop),
});
var docId = params.docId;
var url = "``http://wsp-exttest.lcardtest.corp:4440/rest.oms/MaxRestService/getPDF?docId=``" + docId;
let response = await new Promise(resolve => {
xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onload = function(e) {
resolve(xhr.response);
};
xhr.onerror = function () {
resolve(undefined);
console.error("** An error occurred during the XMLHttpRequest");
};
xhr.send();
})
//
var j = JSON.parse(xhr.responseText);
var pdfData = j[0].content;
var letterFrame = document.getElementById("letterFrame");
letterFrame.src = "data:application/pdf;base64," + pdfData;
/*letterFrame.onreadystatechange = () => {
if (letterFrame.readyState === 'complete') {
alert(letterFrame.readyState);
letterFrame.src = "data:application/pdf;base64," + pdfData;
}
};*/
}
catch(e)
{
if(confirm("Load faile: " + e.message + "click ok to retry"))
setSRC();
}
}
</script>
</head>
<body onload="setSRC()">
<iframe id="letterFrame" width="1200px" height="800px" onload=""></iframe>
Reload
</body>
</html>
Reload

How to get name of the location from Latitude and Longitude I am getting from google geocoder and display in web-app done using apps script

I am able to read latitude and longitude using a geocoder from google. But when I try to get the location name from the JSON object, the web app can't display it. Then tried to display in an alert. And what? Yes, Alert can display the whole address. Then again tried to use the document.getElementById('id') to display same in webApp but can't display.
Here is my code for yetanotherDist.HTML GAS Project file.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="http://maps.google.com/maps/api/js?sensor=false&libraries=geometry" type="text/javascript"></script>
<script src="https://maps.googleapis.com/maps/api/js?key="APIKey"></script>
<script src= "https://maps.googleapis.com/maps/api/js"></script>
<script>
window.onload = function() {
var startPos;
var geoOptions = {
enableHighAccuracy: true
}
var geoSuccess = function(position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
var latlong = new google.maps.LatLng(currentLat, currentLong);
fromLat =startPos.coords.latitude;
fromLng = startPos.coords.longitude;
toLat = 48.8567;
toLng = 2.3508;
distance = google.maps.geometry.spherical.computeDistanceBetween(
new google.maps.LatLng(fromLat, fromLng),
new google.maps.LatLng(toLat, toLng));
document.getElementById("Distance").innerHTML = distance;
geocoder.geocode({'latLng':latlong}, function(results, status){
if (status == google.maps.GeocoderStatus.OK)
{
if (results)
{
document.getElementById("Location").innerHTML = latlong;
document.getElementById("Address").innerHTML = results[0].formatted_address;
alert(results[0].formatted_address);
}
}
else
alert("Could not get the geolocation information");
});
};
var geoError = function(error) {
console.log('Error occurred. Error code: ' + error.code);
// error.code can be:
// 0: unknown error
// 1: permission denied
// 2: position unavailable (error response from location provider)
// 3: timed out
};
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
</script>
</head>
<body>
<div id="startLat">startLat</div>
<div id="startLon">startLon</div>
<div id="Location">Location</div>
<div id="Address">Address</div>
<div id="Distance">Distance</div>
</body>
</html>
Here is the code.gs file
function doGet(e) {
var htmlOutput = HtmlService.createTemplateFromFile('yetanotherDist');
return htmlOutput.evaluate();
}
Very interesting yet I am not able to understand why the location name can't be displayed in webapp. Or I might be missing something. Please help.
There are several errors in the code you posted which makes me wonder if that is the real code or just fantasy '-)
https://maps.googleapis.com/maps/api/js?key="APIKey"
There should not be that extra " before the key.
You have not declared the GeoCoder reference yet you say that your code was able to find (&alert) the address - curious?!
In the test I did I spoofed the location to Mt. Google by lat/lng using Dev Tools sensor and the geocoded result pinpoints Google HQ so I guess it works.
<!DOCTYPE html>
<html>
<head>
<style>
div:before{content:attr(id)': ';color:red;}
body{padding:5rem;font-family:courier}
</style>
<base target="_top">
<script src="//maps.google.com/maps/api/js?libraries=geometry&key=APIKEY"></script>
<script>
window.onload = function() {
var startPos;
var geoOptions = {
enableHighAccuracy: true
};
let geocoder=new google.maps.Geocoder();
var geoSuccess = function(position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
var latlong = new google.maps.LatLng( startPos.coords.latitude, startPos.coords.longitude );
fromLat = startPos.coords.latitude;
fromLng = startPos.coords.longitude;
toLat = 48.8567;
toLng = 2.3508;
distance = google.maps.geometry.spherical.computeDistanceBetween(
new google.maps.LatLng(fromLat, fromLng),
new google.maps.LatLng(toLat, toLng)
);
document.getElementById("Distance").innerHTML = distance;
geocoder.geocode({'latLng':latlong}, function(results, status){
if (status == google.maps.GeocoderStatus.OK){
if (results){
document.getElementById("Location").innerHTML = latlong;
document.getElementById("Address").innerHTML = results[0].formatted_address;
}
} else {
alert("Could not get the geolocation information");
}
});
};
var geoError = function(error) {
console.log('Error occurred. Error code: ' + error.code);
};
navigator.geolocation.getCurrentPosition( geoSuccess, geoError, geoOptions );
}
</script>
</head>
<body>
<div id="startLat">startLat</div>
<div id="startLon">startLon</div>
<div id="Location">Location</div>
<div id="Address">Address</div>
<div id="Distance">Distance</div>
</body>
</html>

Malformed html error thrown from html based object in appscript

I've hit a wall on an issue when I try to display the content.text object in apps script, it returns a malformed html error specifically regarding my fetch to a GET request of
https://www.cloudconnect.xxx...
I get everything I need, but the content.text bit which is throwing a malformed html error in apps script. I'd like to use the html and return the documents as is with proper formatting and believe that I can properly parse this html to apps script using htmloutput as it needs to be sanitized, but I believe it's what's throwing the malformed html object. How can I proceed without escaping html characters? How can I properly parse this? Has anyone been successful at this by any chance?
Example of content.text:
<body>
<!-- [DocumentBodyStart:a63392fa-f859-4513-867e-1f3d2714b006] -->
<div class=\"jive-rendered-content\">
<p>Hi,team!</p>
<p style=\"min-height: 8pt; padding: 0px;\"> </p>
<p>When executing attest () of SafetyNet Attestation API, apkPackageName is obtained as a parameter.</p>
<p>I ran this API several times.</p>
<p>As a result, the apkPackageName parameter was missing only once.</p>
<p>In all other execution results, the parameter apkPackageName is present and will not occur again.</p>
<p style=\"min-height: 8pt; padding: 0px;\"> </p>
<p>Why can't I get the apkPackageName when running the SafetyNet Attestation API on a device that has not been
tampered with?</p>
<p style=\"min-height: 8pt; padding: 0px;\"> </p>
<p>device : Kyocera 704KC</p>
<p style=\"min-height: 8pt; padding: 0px;\"> </p>
<p>Regards,</p>
</div><!-- [DocumentBodyEnd:a63392fa-f859-4513-867e-1f3d2714b006] -->
</body>
Would anyone have any pointers on how to proceed from here? My goal is to obtain the text from the content.text object, which I can see on any regular editor, but not in apps script for some reason while using the html format that it returns as is.
Code.gs
function doGet(request) {
return HtmlService.createTemplateFromFile('Page').evaluate();
}
function include(filename) {
var finalRequest = UrlFetchApp.fetch('https://www.cloudconnect.xxx...');
var data = finalRequest.toString().replace("throw 'allowIllegalResourceCall is false.';", "").trim();
data = JSON.parse(data);
var returnedData = [];
for(var i in data.list){
var content = data.list[i];
var content_subject = JSON.stringify(content.subject);
var content_text = JSON.stringify(content.content.text);
returnedData.push(content_subject + "<br />" + "<br />" + textBody(content_text));
}
return returnedData;
}
function textBody(content){ // <-- where the error throws on the content_text object
return HtmlService.createHtmlOutput(content);
}
var entityMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/',
'`': '`',
'=': '='
};
function escapeHtml(string) {
return String(string).replace(/[&<>"'`=\/]/g, function (s) {
return entityMap[s];
});
}
function myFunction() {
Logger.log(HtmlService
.createTemplateFromFile('Page')
.getCode());
}
Page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('Stylesheet'); ?>
</head>
<body>
<script>
var responseSubject;
var responseContent;
function displayData(responseSubject, responseContent) {
document.getElementById('output').innerHTML = responseSubject + <br> + responseContent + <br>;
}
google.script.run.withFailureHandler(displayData).withSuccessHandler(displayData).include();
</script>
</body>
</html>
Update
I have hit a wall returning the Exception: Cannot call SpreadsheetApp.getUi() from this context. (line 21, file "Code")
Code.gs
function doGet(request) {
return HtmlService.createTemplateFromFile('Page').evaluate();
}
function include(filename) {
var finalRequest = UrlFetchApp.fetch('https://www.cloudconnect.xxx....');
var data = finalRequest.toString().replace("throw 'allowIllegalResourceCall is false.';", "").trim();
data = JSON.parse(data);
var returnedData = [];
for(var i in data.list){
var content = data.list[i];
var contentSubject = JSON.stringify(content.subject);
var contentText = JSON.stringify(content.content.text);
returnedData.push(contentSubject + "<br/>" + "<br/>");
var fixedContent = escapeHtml(contentText);// fixes the malformed Html error
var ui = HtmlService.createHtmlOutput(fixedContent);//the attempt to read the onlick event and load the content text - but it throws the error: Exception: Cannot call SpreadsheetApp.getUi() from this context. (line 21, file "Code")
SpreadsheetApp.getUi().showModelessDialog(ui);
Logger.log("returnedData is: " + returnedData);
}
return returnedData;
}
var entityMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/',
'`': '`',
'=': '='
};
function escapeHtml(string) {
return String(string).replace(/[&<>"'`=\/]/g, function (s) {
return entityMap[s];
});
}
function myFunction() {
Logger.log(HtmlService
.createTemplateFromFile('Page')
.getCode());
}
//function contentBody(responseContent){ <-- realized I can't do this from a custom function
//var html = responseContent;
//var ui = HtmlService.createHtmlOutput(html);
//SpreadsheetApp.getUi().showModelessDialog(ui);
//}
Page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('Stylesheet'); ?>
<script>
var responseSubject;
var responseContent;
function displaySubjects(responseSubject) {
document.getElementById('output').addEventListener('click', getContentBody).innerHTML = responseSubject;
}
google.script.run.withFailureHandler(displaySubjects).withSuccessHandler(displaySubjects).include();
//function displayContentText(responseContent){
//document.getElementById('projection').innerHTML = responseContent;
//}
//google.script.run.withFailureHandler(displayContentText).withSuccessHandler(displayContentText).contentBody();
</script>
</head>
<body>
<p id = "output"></p>
<p id = "projection"></p>
</body>
</html>
My goal here is to add a click listener to the subjects and have them load the content text through the Html service.
Any help would be highly appreciated please.
Cheers!
This works:
function htmltest() {
var html='<body><!--[DocumentBodyStart:a63392fa-f859-4513-867e-1f3d2714b006]--><div class="jive-rendered-content"><p>Hi,team!</p><p style="min-height:8pt;padding:0px;"> </p><p>When executing at test() of Safety NetAttestationAPI, apkPackageName is obtained as a parameter.</p><p>I ran this API several times.</p><p>As a result,the apkPackageName parameter was missing only once.</p><p>In all other execution results,the parameter apkPackageName is present and will not occur again.</p><p style="min-height:8pt;padding:0px;"> </p><p>Whycan\'t I get the apkPackageName when running the Safety NetAttestation API on a device that has not been tampered with?</p><p style="min-height:8pt;padding:0px;"> </p><p>device:Kyocera704KC</p><p style="min-height:8pt;padding:0px;"> </p><p>Regards,</p></div><!--[DocumentBodyEnd:a63392fa-f859-4513-867e-1f3d2714b006]--></body>';
var ui=HtmlService.createHtmlOutput(html).setHeight(500);
SpreadsheetApp.getUi().showModelessDialog(ui, "HTML Test");
}
Here's what I get when I run it just that way it is.

google api- google sign in for website, cannot access the basic profile

I want to get the users' profile, like user id and email address, i have tried many ways to do it, but still get the error of "TypeError: googleUser.getBasicProfile is not a function"
I follow the instruction of google document, but i still get the error:
and here is all code of it:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>googleSignin</title>
<meta name="google-signin-requestvisibleactions" content="https://schema.org/AddAction" />
<meta name="google-signin-scope" content="https://www.googleapis.com/auth/plus.login" />
<meta name="google-signin-client_id" content="589020135825-sbg93psr9i0v8gq6ajm7mv9et38o9ts2.apps.googleusercontent.com">
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark" onclick="onSignIn('googleUser')"></div>
<script>'
function onSignIn(googleUser) {
// Useful data for your client-side scripts:
var profile = googleUser.getBasicProfile();
var user_name = profile.getName();
alter(user_name);
console.log("ID: " + profile.getId());
console.log('Full Name: ' + profile.getName());
console.log('Given Name: ' + profile.getGivenName());
console.log('Family Name: ' + profile.getFamilyName());
console.log("Image URL: " + profile.getImageUrl());
console.log("Email: " + profile.getEmail());
//The ID token you need to pass to your backend:
//var id_token = googleUser.getAuthResponse().id_token;
//console.log("ID Token: " + id_token);
}
function signOut(){
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function() {
console.log('User signed out!');
});
}
function onLoad() {
gapi.load('auth2', function() {
var auth2 = gapi.auth2.init();
auth2.then(function(){
//current values
var isSignedIn = auth2.isSignedIn.get();
var currentUser = auth2.currentUser.get();
if (!isSignedIn) {
//rendering it
gapi.signin2.render('google-signin-button', {
'onsuccess': 'onSignIn'
});
}
});
});
}
</script>
Sign out
<script src="https://apis.google.com/js/platform.js" async defer></script>
</body>
</html>
Comparing your code to the example you don't need the onclick handler in your button div. The parementer you pass via that is a string giving the error. Let platform.js sort out the calling
You might want to add asunc defer to you script as well
see https://developers.google.com/identity/sign-in/web/