【angularjs】外部スクリプトの読込が完了してからコントローラを実行する

今回はGoogleMapを扱う際に気になったのでちゃんと実装してみたのでその時のメモ。htmlにscriptタグを埋め込むやり方が普通なのだろうが、そこでネットワークエラー等が発生するとhtmlを再読み込みしない限り2度と読み込むタイミングがないのではないかということを懸念してこのような形としてみた。

Router

angular.module('starter', ['ionic'])
.config(function($stateProvider) {
  $stateProvider
  .state('map', {
    url: '/map',
    controller: 'MapCtrl',
    resolve: {
      map: function(GoogleMapService) {
        return GoogleMapService.load();
      }
    }
  })
})

Service

angular.module('starter')
.service('GoogleMapService', function($q) {
  this.flag = false

  this.load = function() {
    var deferred = $q.defer()

    if (this.status) {
      deferred.resolve();
    } else {
      var self = this;
      var url = 'https://maps.googleapis.com/maps/api/js';
      var head = document.getElementsByTagName('head')[0];
      var script = document.createElement('script');

      script.src = url + '?key=APIキー';
      head.appendChild(script);

      script.onload = function() {
        self.status = true;
        deferred.resolve();
      };
      script.onerror = function() {
        deferred.reject();
      };
    }

    return deferred.promise
  }
})

さらにちゃんとやるなら、script.onerrorになったときに何度かリトライも実装した方がよいかもしれないが、今回はこんな感じで。以上です。