Best way to use AngularJS with Google API?

4,191 views
Skip to first unread message

Jake Marsh

unread,
Jun 18, 2013, 3:03:13 PM6/18/13
to ang...@googlegroups.com
Right now I'm working on an AngularJS/RequireJS project, using the Google API Javascript Client for authentication/user info. I'm using the Google API for users to login, and then get their email address/contacts. I'm currently doing this in a service. Here it is:

.service('googleLogin', ['$http', '$rootScope', function ($http, $rootScope) {
            var clientId = '{MY CLIENT KEY}',
                apiKey = '{MY API KEY}',
                scopes = 'https://www.googleapis.com/auth/userinfo.email https://www.google.com/m8/feeds',
                domain = '{MY COMPANY DOMAIN}';

            this.handleClientLoad = function () {
                // Step 2: Reference the API key
                gapi.client.setApiKey(apiKey);
                gapi.auth.init(function () { });
                window.setTimeout(checkAuth, 1);
            };

            this.checkAuth = function() {
                gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: true, hd: domain }, this.handleAuthResult );
            };

            this.handleAuthResult = function(authResult) {
                if (authResult && !authResult.error) {
                    gapi.client.load('oauth2', 'v2', function () {
                        var request = gapi.client.oauth2.userinfo.get();
                        request.execute(function (resp) {
                            console.log(userEmail);
                        });
                    });
                }
            };

            this.handleAuthClick = function (event) {
                // Step 3: get authorization to use private data
                gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: false, hd: domain }, this.handleAuthResult );
                return false;
            };

        }]);

I then call it from the controller upon link click with this:

 $scope.login = function () {
            googleLogin.handleAuthClick();
        };

This shows the login dialog and authenticates correctly. However, due to the fact that it's all done asynchronously (i think), I am unable to store any values like user's email address or contacts to pass it to the controller/view. Is there a better way to do this? I have a hunch that I should be using the AngularJS Promise/defer, but I'm not sure if/how that would work with the Google API Javascript Client that I'm currently using. I'm open to replacing this, just not sure what with. Thanks

Jake Marsh

unread,
Jun 18, 2013, 6:11:29 PM6/18/13
to ang...@googlegroups.com
I was right (I think) about using the promise/defer implementation from angularJS.

Here's my final service:
.service('googleLogin', ['$http', '$rootScope', '$q', function ($http, $rootScope, $q) {
            var clientId = '{MY CLIENT ID}',
                apiKey = '{MY API KEY}',
                scopes = 'https://www.googleapis.com/auth/userinfo.email https://www.google.com/m8/feeds',
                domain = '{MY COMPANY DOMAIN}',
                userEmail,
                deferred = $q.defer();

            this.login = function () {
                gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: false, hd: domain }, this.handleAuthResult);

                return deferred.promise;
            }

            this.handleClientLoad = function () {
                gapi.client.setApiKey(apiKey);
                gapi.auth.init(function () { });
                window.setTimeout(checkAuth, 1);
            };

            this.checkAuth = function() {
                gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: true, hd: domain }, this.handleAuthResult );
            };

            this.handleAuthResult = function(authResult) {
                if (authResult && !authResult.error) {
                    var data = {};
                    gapi.client.load('oauth2', 'v2', function () {
                        var request = gapi.client.oauth2.userinfo.get();
                        request.execute(function (resp) {
                            $rootScope.$apply(function () {
                                data.email = resp.email;
                            });
                        });
                    });
                    deferred.resolve(data);
                } else {
                    deferred.reject('error');
                }
            };

            this.handleAuthClick = function (event) {
                gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: false, hd: domain }, this.handleAuthResult );
                return false;
            };

        }]);

And how it's called in the controller:
var promise = googleLogin.login();
                promise.then(function (data) {
                    console.log(data.email);
                }, function (reason) {
                    console.log('Failed: ' + reason);
                });

On Tuesday, June 18, 2013 2:03:13 PM UTC-5, Jake Marsh wrote:
Right now I'm working on an AngularJS/RequireJS project, using the Google API Javascript Client for authentication/user info. I'm using the Google API for users to login, and then get their email address/contacts. I'm currently doing this in a service...

Rahul Dhawani

unread,
Jan 3, 2016, 6:47:03 AM1/3/16
to AngularJS
Hi Jake,
I see you are using timeout for 1sec to load all the necessary file(which is loaded automatically), but do you think its the right way to it? I mean what if internet connectivity is slow and it takes more than 1sec to load? I was also stuck to same problem, came with exact same solution. But somehow I dont think its right way to do.
Reply all
Reply to author
Forward
0 new messages