Sign-in with google user in an AngularJS app

All we need is an easy explanation of the problem, so here it is.

I read this tutorial in order to connect my AngularJS app with google sign-in. I added the google button as follows (just copy-pasting the tutorial):

In the head I added the meta tag:

<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">

And then added the button itself:

<div class="g-signin2" data-onsuccess="onSignIn"></div>

At first I just copied the onSignIn method (that’s just a generic handler so I’m not copying it to the question) from the tutorial and put it in a <script>...</script> tag and it worked. I now want to put this method in an Angular controller. So I created a controller as follows:

app.controller('GoogleCtrl', function() {
  function onSignIn(googleUser) {
    var profile = googleUser.getBasicProfile();
    console.log('ID: ' + profile.getId());
    console.log('Name: ' + profile.getName());
    console.log('Image URL: ' + profile.getImageUrl());
    console.log('Email: ' + profile.getEmail());
   }
}

And wrapped the button with a div:

<div ng-controller="GoogleCtrl">
    <div class="g-signin2" data-onsuccess="onSignIn"></div>
</div>

My code doesn’t get to the onSignIn method now and I’m trying to figure out what can I do.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

If you follow the instructions, what you will end up with is window. onSignIn – try to run it in your browser JS console, now to have the same behaviour you will need to crate that function from your controller.

app.controller('GoogleCtrl', function() {
  function onSignIn(googleUser) {
    var profile = googleUser.getBasicProfile();
    console.log('ID: ' + profile.getId());
    console.log('Name: ' + profile.getName());
    console.log('Image URL: ' + profile.getImageUrl());
    console.log('Email: ' + profile.getEmail());
   }
  window.onSignIn = onSignIn;
}

Remember that code executed by 3rd party like onSignIn will need to call $scope.$digest, so angular is aware of model changes.

Method 2

Looking at your code, it seems like you might have to add listener for your function. To keep things simple, you can easily integrate google login in your app with this plugin. https://github.com/sahat/satellizer

Method 3

You didn’t specify your version of AngularJS, but it shouldn’t matter. I solved this for AngularJS 1.x as follows:

allControllers.controller('authenticateController', ['$rootScope', $scope', function($rootScope, $scope) {
  // do whatever you're doing on this page...
  // initialize The GoogleAuth API explicitly
  // The load an init below can be placed in your app.js in you feel like you want to implement the whole lifecycle Google provides.
  gapi.load('auth2', function() { // Loads the auth2 component of gapi
    gapi.auth2.init({ // initialize the auth2 using your credentials
      client_id: $GOOGLE_API_CLIENT_ID
    }).then(function onInit() { // on complete of init
      gapi.signin2.render("g-signin2", { // render the HTML button on the screen providing the ID of the element (g-signin2)
        onsuccess: function(googleUser) { // This executes when a user successfully authorizes you to their data by clicking the button and selecting their account.
          var profile = googleUser.getBasicProfile();
          console.log('ID: ' + profile.getId());
          console.log('Name: ' + profile.getName());
          console.log('Image URL: ' + profile.getImageUrl());
          console.log('Email: ' + profile.getEmail());
          // Do whatever you need to do to authenticate on your site.
        }
      });
    });
  });
}]);
// In your index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.8/angular.min.js"></script>
<script type="text/javascript" src="https://apis.google.com/js/platform.js" async defer></script>

// In your login fragment
<div id="g-signin2" style="width: 200px; margin: 20px auto 20px auto;"></div>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply