lazyload both on the loaded page, as well as in the modal open close reopen

I want to have lazyload both on the loaded page, as well as in the modals.

So as far as I understand the lazyLoad object must be created initially invoked on the start by angular.js
Then the question is how to make it work also for the modal.

actualy when I first go to the page address.html that contains a button (called Fill Address) that trigger a Modal with the autocomplet address to fill.
It works juste fine in the first time.

And I get the following logs from my js codes

1- loadScript from LazyLoadApi.js lazyLoadApi.js
2- initAutocomplete calledddddddd. googleMap.js
3- maps-API has been loaded, ready to use initAutocomplete googleMap.js
4- Modal opened and LoadLazyAPI service called. address-list.js
5- Modal opened and LoadLazyAPI service called. END END address-list.js
6- geolocate called From controller.

but when I close the modal and click again on the button (Fill address) the modal reopen again but this time the autocomplete address is not working
And I get the following logs from my js codes

2-initAutocomplete calledddddddd. googleMap.js
3-maps-API has been loaded, ready to use initAutocomplete googleMap.js
4-Modal opened and LoadLazyAPI service called. address-list.js.js:88:14
5-Modal opened and LoadLazyAPI service called. FIN FIN address-list.js
6-geolocate called From controller.

the step one 1- loadScript from LazyLoadApi.js lazyLoadApi.js is obviousely not made because it’s created initially on the loaded page and not for the case the modal opened closed and reopened.

so when we force refresh page on the browser

we get again

1- loadScript from LazyLoadApi.js lazyLoadApi.js
2- initAutocomplete calledddddddd. googleMap.js
3- maps-API has been loaded, ready to use initAutocomplete googleMap.js
4- Modal opened and LoadLazyAPI service called. address-list.js
5- Modal opened and LoadLazyAPI service called. END END address-list.js
6- geolocate called From controller.

I hope the following next lines clarifies more what I am looking for:

I have the following service:

angular.module('App').service('lazyLoadApi',['$window','$q', function lazyLoadApi($window, $q) {

    function loadScript()  {
           console.log('loadScriptt from LazyLoadApi.js')
            // use global document since Angular's $document is
            // weak 
            var s = document.createElement('script');
            s.src = '//maps.googleapis.com/maps/api/js?key=KEY_TOBEPUTTEDHERE_KEY_TOBEPUTTEDHERE&libraries=places&callback=initAutocomplete';
            document.body.appendChild(s)
    }   

    var ThislazyLoadApi= this;
    var deferred = $q.defer();


    ThislazyLoadApi.loadScript = function() {

        console.log('loadScriptt from LazyLoadApi.js')
        // use global document since Angular's $document is
        // weak 
        var s = document.createElement('script');
        s.src = '//maps.googleapis.com/maps/api/js?key=KEY_TOBEPUTTEDHERE_KEY_TOBEPUTTEDHERE&libraries=places&callback=initAutocomplete';
        document.body.appendChild(s)

    }

        $window.initAutocomplete = function() {
          //loadScript();  
        deferred.resolve();
      }

        if(!window.location.hash) {
            window.location = window.location + '#loaded';
            window.location.reload();
        }else{
          //Init stuff here
            if(document.readyState == 'complete')
                   loadScript();  
        }


      if ($window.attachEvent) {
            $window.attachEvent('onload', loadScript)
          } else {
            $window.addEventListener('load', loadScript, false)
      }

      return deferred.promise;
}]);

How to invoke from the first controler that open the modal to invoke this lazyLoadApi service callback named

function loadScript()  {
               console.log('loadScriptt from LazyLoadApi.js')
                // use global document since Angular's $document is
                // weak 
                var s = document.createElement('script');
                s.src = '//maps.googleapis.com/maps/api/js?key=KEY_TOBEPUTTEDHERE_KEY_TOBEPUTTEDHERE&libraries=places&callback=initAutocomplete';
                document.body.appendChild(s)
        } 

I tried in the first controller that shows the modal to access the service via (Dependecy injection is made to the contoller for $injector)

ModalService.showModal({
            }).then(function (modal) {              

    var flazyloadApi = $injector.get('lazyLoadApi');
                    flazyloadApi.loadScript();

but error loadScript is Not function is thrown.

For more info on my code :

I have a directive called googleMap

angular.module('App').directive('googleMap',['$rootScope','lazyLoadApi','$parse', '$timeout', function($rootScope, lazyLoadApi,$parse,$timeout) {

     var directive = {      
            restrict: 'CA', // tells Angular to apply this to only html tag that is <CA> 
                            //restrict by class name
            link: link,
            controller: controller,
            scope: {// create two isolated scope variables 'longitude','latitude' and pass 'vide' to it.

                longitude : '=',
                latitude : '='
             },
             scope: true,
             };

            return directive;

             function link($scope,$window,element, attrs) {

                  //Loads google map script
                  lazyLoadApi.then(initAutocomplete(true));

                  var location = null;
                  var map = null;
                  var mapOptions = null;

                  var placeSearch, autocomplete;

                  var componentForm = {

                      street_number: 'short_name',
                      locality: 'long_name',
                      postal_code: 'short_name'
                 };

                      // Initialize the map
                      $scope.initAutocomplete = function() {    
                      console.log('initAutocomplete calledddddddd.');
                      console.log('maps-API has been loaded, ready to use initAutocomplete');
                      var input = document.getElementById('autocomplete');
                      var options = {
                        types: ['(geocode)'],
                        componentRestrictions: {country: 'MA'}
                      };

                      // Create the autocomplete object, restricting the search to geographical
                      // location types.
                      autocomplete = new google.maps.places.Autocomplete(
                          /** @type {!HTMLInputElement} */(input),
                          {types: ['geocode']});


                      // When the user selects an address from the dropdown, populate the address
                      // fields in the form.
                      autocomplete.addListener('place_changed', fillInAddress);
                      }//fin initAutocomplete         


                      lazyLoadApi.then(function(){
                           // Promised resolved
                           $scope.initAutocomplete();
                       }, function () {
                           // Promise rejected
                       });//END LOADS 

                 function fillInAddress() {
                     console.log('fillInAddress calledddddddd.');
                    // Get the place details from the autocomplete object.
                    var place = autocomplete.getPlace();

                    for (var component in componentForm) {
                      document.getElementById(component).value = '';
                      document.getElementById(component).disabled = false;

                    }

                    // Get each component of the address from the place details
                    // and fill the corresponding field on the form.
                    for (var i = 0; i < place.address_components.length; i++) {
                      var addressType = place.address_components[i].types[0];
                      if (componentForm[addressType]) {
                        var val = place.address_components[i][componentForm[addressType]];
                        document.getElementById(addressType).value = val;
                     }
                    }

                    // Get each component of the address from the place details
                    // and fill the corresponding scop element on the form.
                    for (var i = 0; i < place.address_components.length; i++) {
                      var addressType = place.address_components[i].types[0];
                      if (componentForm[addressType]) {
                        var val = place.address_components[i][componentForm[addressType]];


                     if (addressType =='street_number'){

                          var e0 = document.getElementById(addressType);
                            var scopeApp = angular.element(e0).scope();
                            scopeApp.$apply(function(){ scopeApp.addressNumber = val.toString()});
                      }
                     else if (addressType =='locality'){


                            var el = document.getElementById(addressType);
                          var scopeApp = angular.element(el).scope();
                          scopeApp.$apply(function(){ scopeApp.city = val.toString()});
                      }
                        else if (addressType =='postal_code')
                      {
                            var e2 = document.getElementById(addressType);
                          var scopeApp = angular.element(e2).scope();
                          scopeApp.$apply(function(){ scopeApp.zipCode = val.toString()});
                      }

                     }
                    }

                    var e3 = document.getElementById('autocomplete');
                    var scopeApp1 = angular.element(e3).scope();
                    scopeApp1.$apply(function(){scopeApp1.addresse = place.formatted_address.toString()});
                  }//END fillInAddress


        }//END Link 
             function controller($scope, $attrs) {
                //$timeout(function() {
                var getter = $parse($attrs.name);
                getter.assign($scope.$parent, this);
                    this.geolocate = function() {
                    console.log('geolocate calledddddddd From Directivvvvve.');
                    // Bias the autocomplete object to the user's geographical location,
                    // as supplied by the browser's 'navigator.geolocation' object.
                      if (navigator.geolocation) {
                          var location_timeout = setTimeout("geolocFail()", 10000);
                          navigator.geolocation.getCurrentPosition(function(position) {
                          clearTimeout(location_timeout);
                          var geolocation = {
                            lat: scope.latitude,
                            lng: scope.longitude
                          };
                          //var lat = position.coords.latitude;
                          //var lng = position.coords.longitude;
                          geocodeLatLng(lat, lng);
                          var circle = new google.maps.Circle({
                            center: geolocation,
                            radius: position.coords.accuracy
                          });
                          autocomplete.setBounds(circle.getBounds());
                        }, function(error) {
                            clearTimeout(location_timeout);
                            geolocFail();
                        });
                    } else {
                        // Fallback for no geolocation
                        geolocFail();
                    }

                };//Fin geolocate
            }


}]);

And this from the first controller from where we invoke showModal

ModalService.showModal({
                templateUrl: "templates/address/create-address.html",
                controller: "CreateAddressCtrl",
                preClose: (modal) => { modal.element.modal('hide');},
                inputs: {
                    title: 'Fill Address',
                    : {}
                }
            }).then(function (modal) {
                var flazyloadApi = $injector.get('lazyLoadApi');
                flazyloadApi.loadScript();

                console.log('Modal opened and LoadLazyAPI service called. ');
                 // Loads google map script
                //lazyLoadApi.then(initAutocomplete(0));//FIN LOADS

                console.log('Modal opened and LoadLazyAPI service called. END END ');


                modal.element.modal({backdrop: 'static'});
                $scope.someFn = function() {
                    $scope.foo.geolocate();
                };
                function geolocate () {
                    console.log('geolocate called From controller.');
                    // Bias the autocomplete object to the user's geographical location,
                    // as supplied by the browser's 'navigator.geolocation' object.
                      if (navigator.geolocation) {
                          var location_timeout = setTimeout("geolocFail()", 10000);
                          navigator.geolocation.getCurrentPosition(function(position) {
                              clearTimeout(location_timeout);
                          $scope.longitude =position.coords.latitude;
                          $scope.latitude =position.coords.longitude; 
                        }, function(error) {
                            clearTimeout(location_timeout);
                           // geolocFail();
                        });
                    } else {
                        // Fallback for no geolocation
                        //geolocFail();
                    }

                };//Fin geolocate

                geolocate();

                modal.close.then(function (result) {
                    // First getting rid of the google.maps object (to avoid memory leaks)
                    // Then, we are also removing google-maps related script tags we can identify.
                    // After unloaded, if maps is reloaded more than once on the same page; 
                    // we'll also get a warning in the console saying: "Warning: you have included the
                    // Google Maps API multiple times on this page. This may cause unexpected errors."
                    // This script will also avoid that warning.
                    if (window.google !== undefined && google.maps !== undefined) {
                        delete google.maps;
                        $('script').each(function () {
                            if (this.src.indexOf('googleapis.com/maps') >= 0
                                    || this.src.indexOf('maps.gstatic.com') >= 0
                                    || this.src.indexOf('earthbuilder.googleapis.com') >= 0) {
                                // console.log('removed', this.src);
                                $(this).remove();
                            }
                        });
                    }     
                    if (result) {

                        $scope.addAlert(result.type, result.msg);

                    }

                });
            });

        }

the create-address.html modal

<div id="myModal" class="modal fade"> 
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" ng-click="close()" data-dismiss="modal"
                        aria-hidden="true">&times;</button>
                <h4 class="modal-title">{{title}}</h4>
            </div>
            <div class="modal-body">
                <alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">
                    {{alert.msg}}
                </alert>

                <form name="myForm" class="form-horizontal">

                    <div id="locationField" class="form-group" autocomplete="on">                       
                                 <label class="col-sm-3 control-label">Address</label>
                               <div class="col-sm-9">
                                    <style>
                                        .pac-container {
                                            z-index: 10000 !important;
                                        }
                                    </style>
                                    <input  google-map name="foo"  id="autocomplete" 
                                           placeholder="Enter your address" 
                                           class="form-control" 
                                           ng-model="addresse" 
                                           type="text" maxlength="60" 
                                           ng-focus="geolocate()"
                                           required autofocus>
                               </div>
                          </div>

                       <div class="form-group" autocomplete="on">                       
                              <label class="col-sm-3 control-label">Numero</label>
                               <div class="col-sm-9">
                                    <input id="street_number"  class="form-control"  disabled="true" 
                                           ng-model="addressNumber"  autocomplete="on"
                                           type="text" maxlength="40"
                                           placeholder="numero" required autofocus>
                               </div>
                          </div>

                          <div class="form-group" autocomplete="on">                       
                              <label class="col-sm-3 control-label">City</label>
                               <div class="col-sm-9">
                                    <input id="locality"  class="form-control"  disabled="true" 
                                           ng-model="city"  autocomplete="on"
                                           type="text" maxlength="40"
                                           placeholder="city" required autofocus>
                               </div>
                          </div>  
                     <div class="form-group" autocomplete="on">                       
                        <label class="col-sm-3 control-label">Zip Code</label>
                               <div class="col-sm-9">
                                    <input id="postal_code" class="form-control"
                                           ng-model="zipCode" autocomplete="on" type="text" 
                                           ng-pattern='/^(d{5}(-d{4})?|[A-Z]d[A-Z] *d[A-Z]d)$/' 
                                           maxlength="5"
                                           disabled="true"
                                           placeholder="zipCode" required autofocus>
                               </div>
                      </div>
                    <div class="form-group">                       
                        <label class="col-sm-3 control-label">Address2</label>
                               <div class="col-sm-9">
                                    <input id="addresse" class="form-control" ng-disabled="!address.name" ng-model="addresse" 
                                           value='{{address.name}}'
                                          type="text" maxlength="60"
                                           placeholder="addresse" required>{{address.name}}
                               </div>
                    </div>

                      <div class="form-group">                       
                        <label class="col-sm-3 control-label">City</label>
                               <div class="col-sm-9">
                                    <input id="city"  class="form-control" ng-model="city"  ng-disabled="!address.name" type="text" maxlength="40"
                                          value='{{address.components.city}}' placeholder="city" required>{{address.components.city}}
                               </div>
                      </div>

                     <div class="form-group">                       
                        <label class="col-sm-3 control-label">Zip Code</label>
                               <div class="col-sm-9">
                                    <input id="zip" class="form-control" ng-disabled="!address.name" ng-model="zipCode" type="text" ng-pattern='/^(d{5}(-d{4})?|[A-Z]d[A-Z] *d[A-Z]d)$/' maxlength="5"
                                          value='{{address.components.postCode}}' placeholder="zipCode" required>{{address.components.postCode}}
                               </div>
                      </div>

            </form>
            <div class="modal-footer">
                <button type="button" ng-click="createAddress()" class="btn btn-primary">Save</button>
                <button type="button" ng-click="cancel()" class="btn">Cancel</button>
            </div>
        </div>
    </div>
</div>
</div>

the modal controler CreateAddressCtrl

// modal controler
angular.module('App').controller('CreateAddressCtrl',
    ['$scope','$window', '$element','$http','$injector','lazyLoadApi','$cacheFactory','safeApply', 'close', 'title',
        function ($scope, $window,$element,$http,$injector,lazyLoadApi,$cacheFactory,safeApply,close,title) {
    ***********************************
 }]);

Source: AngularJS