1

I'm having an issue using the Google Api in my angularjs 1.3 (SPA using ui.router). Per the google api instructions, I added a reference to the client.js file with a call back in my index.html head,

   <html ng-app="myApp">
    <head>
        
        <script src="Scripts/jquery-2.1.3.min.js"></script>

        <script src="Scripts/angular.min.js"></script>
        <script src="Scripts/angular-ui-router.min.js"></script>
    <script>
    function LoadGAPI() {
       
    }
    </script>
    <script type="text/javascript" src="https://apis.google.com/js/client.js?onload=LoadGAPI"></script>

As I understand, client.js will asynchronously load the full client api, and when complete call the defined function LoadGAPI.

Sometimes LoadGAPI is called before my angular app .run is called, and sometimes it is not. I don't mind that it loads asynchonously.. but how can I alert my angular app that it is indeed ready for use?

2
  • might be a silly question, but why don't you load GAPI after your code? Commented Mar 16, 2015 at 20:52
  • Because GAPI loads asynchronously, I still need to know when it is ready. Can LoadGAPI() in my example above, call a Controller perhaps? Commented Mar 16, 2015 at 21:00

1 Answer 1

1

I faced something similar before and there are two ways of solving it, one is delaying the whole angular's bootstrapping till the other library gets loaded by triggering it manually after LoadGAPI and dom ready, something like:

var n = 0;

function LoadGAPI () {
  
  // Only pass after the first call
  if (n++) {

    angular.bootstrap(angular.element(document).find('html'), ['app']);
  }
};

angular.element(document).ready(LoadGAPI);

and the other one is ensuring the library's presence only for the ui-router states needing it using resolve:

State

$stateProvider
        ...
        .state('some.state', {
            url        : '/some',
            templateUrl: 'view/some.state.html',
            controller : 'some.state',
            resolve    : GAPI.resolver
        })
        ...

Resolver

var GAPI = {
    ready   : false,
    resolver: {
        api: ['$q', function($q) {

            if (!GAPI.deferred) {

                GAPI.deferred = $q.defer();
            }

            if (GAPI.ready) {

                GAPI.deferred.resolve();
            }

            return GAPI.deferred.promise;
        }]
    }
};

window.LoadGAPI = function () {

    GAPI.ready = true;

    if (GAPI.deferred) {

        GAPI.deferred.resolve();
    }
};

The second one can be simplified, but I hope you get the idea.

Sign up to request clarification or add additional context in comments.

2 Comments

kind of combined your solution with @maurycy note above. Loading gapi first, then angular would work as you suggest, but I prefer to have my app load first, in case the load is slow or needs authorization/authentication. I came up with this plnkr.co/edit/GqyxnVKUfEaMaljpoZAT. Basically my app loads, and the Orders state requires google api, it waits. I'm new to plunker and stackoverflow, so its kind of primitive, not much on the ui but I'm going to roll with it for now.
I'm glad to see you've managed it. Anyway, the second approach addresses just that, having the app already running and waiting for the library to load only on the states needing it. Cheers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.