1

I'm developing an app (in my local machine) which displays various locations (an array that varies in size) in an accordion. I'm using the accordion and pagination directives from Angular UI Bootstrap with the Google Maps JS API-based directives from Angular Google Maps.

I have an issue where sometimes the map loads in the first item I clicked, then I click on another item in the accordion and the map doesn't load. Then a few minutes later, I'll refresh my browser and I click on the same item and the map will load. Then if I go to another page in the pagination, the maps aren't displayed there. As you can see in my code, I'm only calling the maps when I click on an item in the accordion, not when the items are loaded. I don't want a lot of maps to be loaded right away if the size of the locations array is large.

Here is a plunker demonstrating the problem, and here is a fiddle.

Here is some code from the example linked above which I think is important to the problem:

HTML body

<accordion close-others="oneAtATime">
    <accordion-group is-open="status.open" ng-repeat="location in locations | startFrom: (currentPage-1)*5| limitTo: 5">
        <accordion-heading >
            <strong get-map-dir location-index={{$index}}>Location</strong> - {{location.address1}}
        </accordion-heading>
        <div id="branch_map" class="" ng-show="showMap ">
            <ui-gmap-google-map center='location.mapInfo.map.center' zoom='location.mapInfo.map.zoom'>
                <ui-gmap-marker coords="location.mapInfo.marker.coords" options="location.mapInfo.marker.options" idkey="location.mapInfo.marker.id">
                    <ui-gmap-window ng-cloak closeClick="closeClick()">
                    </ui-gmap-window>
                </ui-gmap-marker>
            </ui-gmap-google-map>
        </div>
    </accordion-group>

    <pagination total-items="locations.length" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()" ng-hide="locations.length < itemsPerPage"></pagination>
</accordion>

JS (partial)

  .factory('anotherService', function() {
    //getMap using google-maps directive from angularjs-ui
    var getMap = function(locationObj, outerCallBack) {
      console.info('get map');
      var mapInfo = {};
      var address = locationObj.address1;
      var zoom = 16;
      var geocoder = new google.maps.Geocoder();
      console.log(locationObj);

      geocoder.geocode({
        "address": address, //required
        "region": 'CA' //CA for canada
      }, function(results, status) {

        if (status == google.maps.GeocoderStatus.OK && results.length > 0) {

          var location = results[0].geometry.location,
            lat = location.lat(),
            lng = location.lng();

          mapInfo.map = {
            center: {
              latitude: lat,
              longitude: lng
            },
            zoom: zoom
          };

          mapInfo.marker = {
            id: 0,
            coords: {
              latitude: lat,
              longitude: lng
            },
            options: {
              title: address
            }

          };
          outerCallBack({
            success: true,
            mapInfo: mapInfo
          });

        } else if (status === google.maps.GeocoderStatus.ZERO_RESULTS) {
          console.info("Geocoder was sucessful but has no results");
          console.info("address =" + address);
          return;
        } else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
          console.error("You are over your query limit");
          console.info("address =" + address);
          return;
        } else if (status === google.maps.GeocoderStatus.REQUEST_DENIED) {
          console.error("Your request has been denied by Geocoder");
          return;
        } else if (status === google.maps.GeocoderStatus.INVALID_REQUEST) {
          console.error("Invalid Geocoder request");
          return;
        } else {
          console.error("Google Maps in Ctrl failed");
          console.error("address  =" + address);
          return;
        }

      });


    };

    var anotherService = {
      getMap: getMap
    };
    return anotherService;
  })

.directive('fetchMap', function($timeout, anotherService) {
  return {
    restrict: 'A',

    link: function(scope, elem, attrs) {

      console.log("get map dir");
      console.log(scope);
      console.log(elem);
      console.log(attrs);
      elem.bind('click', function(event) {
        //   console.clear();
        console.log("You clicked on me");
        console.log(scope.locations[attrs.locationIndex].mapInfo);

        if (angular.isUndefined(scope.locations[attrs.locationIndex].mapInfo)) {
          anotherService.getMap(scope.locations[attrs.locationIndex], function(callBackfunc) {
            console.info("Getting maps");
            //  scope.showPreloader = false;
            scope.locations[attrs.locationIndex].mapInfo = callBackfunc.mapInfo;
            $timeout(function() {
              scope.showMap = true;
            }, 2000);

          });
        }

      });
    }
  };
})
7
  • where's your ng-click logic? Commented Apr 22, 2015 at 18:21
  • I'm using a directive getMapDir then binding the 'click' event. Dont think i need a ng-cilck logic Commented Apr 22, 2015 at 18:42
  • This is a good reference for you: github.com/angular-ui/angular-google-maps/blob/master/example/…. Commented Apr 22, 2015 at 18:46
  • I've looked at that but sadly it doesnt help. I can display 5 maps but anything more than 5, I dont get any maps at all. Commented Apr 22, 2015 at 20:36
  • I think this doesn't have much to do with map but bootstrap's handling of multiple instances from what I've come across so far. I will get back to you if I find a solution for that. Commented Apr 22, 2015 at 22:27

0

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.