I followed this link https://developers.google.com/identity/sign-in/web/sign-in to get Google Signin on Angular-based website.
I have seen some weird behavior. The signin button sometimes show but not always. When I refresh a page, only 1 in 5 refreshes, the button appears.
I tried in Chrome and Safari and both has same behavior.
Code:
index.html
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-client_id" content="my_client_id">
login.html
<div class="g-signin2" data-onsuccess="onSignIn"></div>
login.js
angular.module('app').controller('LoginCtrl', function($scope) {
window.onSignIn = function(googleUser) {
// Get some info
}
});
My guess is that the platform.js script waits for the DOM-ready event and then looks for your div with the "g-signin2"-class. Though, in Angularjs things work a little different. The reason that it works sometimes, is because sometimes your div has been rendered by Angular and sometimes is hasn't been rendered before the Dom-ready event. There's documentation on how to get the same result with your own javascript. I made an example that follows your routing.
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div ng-view></div>
<script src="https://apis.google.com/js/platform.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<script src="https://code.angularjs.org/1.4.6/angular-route.min.js"></script>
<script>
angular.module('app',['ngRoute'])
.config(['$routeProvider',function($routeProvider){
$routeProvider
.when('/log-in', {
template: '<button ng-click="logInCtrl.onLogInButtonClick()">Log In</button>',
controller: 'LogInController',
controllerAs: 'logInCtrl'
}).otherwise({
redirectTo:'/log-in'
});
}])
.controller('LogInController',function(){
var self = this; //to be able to reference to it in a callback, you could use $scope instead
gapi.load('auth2', function() {//load in the auth2 api's, without it gapi.auth2 will be undefined
gapi.auth2.init(
{
client_id: 'CLIENT_ID.apps.googleusercontent.com'
}
);
var GoogleAuth = gapi.auth2.getAuthInstance();//get's a GoogleAuth instance with your client-id, needs to be called after gapi.auth2.init
self.onLogInButtonClick=function(){//add a function to the controller so ng-click can bind to it
GoogleAuth.signIn().then(function(response){//request to sign in
console.log(response);
});
};
});
});
</script>
</body>
</html>
Or as a directive:
<!doctype html>
<html lang="en" ng-app="app" ng-controller="MainController">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<google-sign-in-button on-sign-in="onSignIn(response)" g-client-id="CLIENTID.apps.googleusercontent.com"></google-sign-in-button>
<script src="https://apis.google.com/js/platform.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<script>
angular.module('app',[])
.controller('MainController',['$scope', function ($scope) {
$scope.onSignIn=function(response){
console.log(response);
}
}])
.directive('googleSignInButton',function(){
return {
scope:{
gClientId:'@',
callback: '&onSignIn'
},
template: '<button ng-click="onSignInButtonClick()">Sign in</button>',
controller: ['$scope','$attrs',function($scope, $attrs){
gapi.load('auth2', function() {//load in the auth2 api's, without it gapi.auth2 will be undefined
gapi.auth2.init(
{
client_id: $attrs.gClientId
}
);
var GoogleAuth = gapi.auth2.getAuthInstance();//get's a GoogleAuth instance with your client-id, needs to be called after gapi.auth2.init
$scope.onSignInButtonClick=function(){//add a function to the controller so ng-click can bind to it
GoogleAuth.signIn().then(function(response){//request to sign in
$scope.callback({response:response});
});
};
});
}]
};
});
</script>
</body>
</html>
After writing the previous examples I found a better and easier way to implement it. With this code you inherit the same button as you normally would.
<!doctype html>
<html lang="en" ng-app="app" ng-controller="MainController">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta name="google-signin-client_id" content="CLIENTID.apps.googleusercontent.com">
</head>
<body>
<google-sign-in-button button-id="uniqueid" options="options"></google-sign-in-button>
<script src="https://apis.google.com/js/platform.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<script>
angular.module('app', [])
.controller('MainController', ['$scope',
function($scope) {
//for more options visit https://developers.google.com/identity/sign-in/web/reference#gapisignin2renderwzxhzdk114idwzxhzdk115_wzxhzdk116optionswzxhzdk117
$scope.options = {
'onsuccess': function(response) {
console.log(response);
}
}
}
])
.directive('googleSignInButton', function() {
return {
scope: {
buttonId: '@',
options: '&'
},
template: '<div></div>',
link: function(scope, element, attrs) {
var div = element.find('div')[0];
div.id = attrs.buttonId;
gapi.signin2.render(div.id, scope.options()); //render a google button, first argument is an id, second options
}
};
});
</script>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With