So I have tried the following templates trying to integrate this:
HTML:
<google-sign-in-button button-id="login-button" options="options"></google-sign-in-button>
CSS:
.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());
}
};
})
--
I've also just tried doing this in the header and using the regular sign in button:
HTML:
<div class="g-signin2" data-onsuccess="onSignIn"></div>
IN THE HEADER:
<script>
window.onLoadCallback = function(){
gapi.auth2.init({
client_id: '123.apps.googleusercontent.com'
});
}
</script>
No matter what I do, i can't figure out how to log a user out. In my controller, when i try and do gapi.auth.signOut();
it says gapi is undefined
EDIT:
I've also tried dabbling in this to log a person out on run but ideally i'd want to make a log out work anywhere and not just when the page loads. I just don't really know where to put it or the correct way to make it happen:
.run(function ($rootScope, $state) {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init();
auth2.then(function(){
auth2.signOut();
});
});
})
EDIT #2:
I also tried to create this factory with a resolve on my ui-router but it's not getting the data in time or at all
.factory('Auth', function($http, $state, $q, $rootScope) {
var factory = { loggedIn: loggedIn };
return factory;
function loggedIn() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init();
auth2.then(function(){
return auth2.isSignedIn.get();
});
});
}
})
EDIT #3:
I tried creating a service but I keep getting the following error for some reason to even test it:
Error: undefined is not an object (evaluating 'gapi.auth2.init')
.service('googleService', ['$http', '$rootScope', '$q', function ($http, $rootScope, $q) {
var self = this;
this.signedIn = function() {
auth2 = gapi.auth2.init();
auth2.then(function(){
return auth2.isSignedIn.get();
});
}
this.signOut = function(){
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
});
}
}])
.controller('login', ['$rootScope', '$scope', '$q', 'googleService', function ($rootScope, $scope, $q, googleService) {
console.log(googleService.signedIn());
}])
I build upon my fiddle from my previous answer on a related question. Basically what I added was a function to the controller scope that would be called when a user clicks on the signout button.
angular.module('app', [])
.controller('MainController', ['$scope',
function($scope) {
$scope.isSignedIn = false;
...
$scope.signOut = function(){
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
$scope.$apply(function(){
$scope.isSignedIn = false;
console.log('User signed out.');
});
});
}
}
])
I used the code snippet provided by Google documentation and that seemed to work immediately.
Do pay attention when changing variables in scope, you have to wrap your scope changes in $scope.$apply
for angular to force to check changes in scope.
You can find the full code in this fiddle.
(I will be removing this Google api project at some point, so replace the API Key with your own if it doesn't work)
This is demo code, so if you would actually put this in project, I'd recommend hiding some of the complexity behind services and directives.
Update: if you want to use a service, you'll have to use angulars promises heavily, see $q docs.
Here's a sample on how you could create a service using promises and callbacks. There's no simple way to get around the callback hell. But I hope wrapping these things into a service will solve that partially.
Here's an updated fiddle taking advantage of the service. This is the js code:
angular.module('app', [])
.controller('MainController', ['$scope','googleService',
function($scope, googleService) {
$scope.isSignedIn = false;
googleService.load().then(function(){
$scope.signIn = function(){
googleService.signIn().then(function(){
$scope.isSignedIn = googleService.isSignedIn();
});
};
$scope.signOut = function(){
googleService.signOut().then(function(){
$scope.isSignedIn = googleService.isSignedIn();
});
};
});
}
])
.service('googleService', ['$q', function ($q) {
var self = this;
this.load = function(){
var deferred = $q.defer();
gapi.load('auth2', function(){
var auth2 = gapi.auth2.init();
//normally I'd just pass resolve and reject, but page keeps crashing (probably gapi bug)
auth2.then(function(){
deferred.resolve();
});
addAuth2Functions(auth2);
});
return deferred.promise;
};
function addAuth2Functions(auth2){
self.signIn = function() {
var deferred = $q.defer();
auth2.signIn().then(deferred.resolve, deferred.reject);
return deferred.promise;
};
self.isSignedIn = function(){
return auth2.isSignedIn.get();
}
self.signOut = function(){
var deferred = $q.defer();
auth2.signOut().then(deferred.resolve, deferred.reject);
return deferred.promise;
};
}
}]);
Basically, inside the load function you wrap the complexity of loading gapi, and auth2. After the load promise resolved in your controller, you are certain that the signIn
, signOut
, etc will work because it is loaded.