Search code examples
javascriptangularjsgoogle-maps-api-3angular-google-mapsweb-frontend

Bug in display of marker info in angular google map


Onclick of marker pops up the info box, but I am not able to display the name or the details, which does display correctly in the java script console attached on a click

I am really confused how to get the infos to display correctly on click of marker. I tried to put the $scope.info in onClick function, but its still not getting displayed.

Can anyone help me fix the bug. I am not too much experienced in front end

Part of Relevant html file:

<div ng-controller="mapCtrl">
 <ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="options" bounds="map.bounds">
    <ui-gmap-markers models="markers" idkey="markers.id" coords="'coords'" click="'onClick'" fit="true" events="markers.events">
        <ui-gmap-window coords="MapOptions.markers.selected.coords" show="windowOptions.show"  options="windowOptions" closeClick="closeClick()">
      <div>{{mapCtrl.info}}</div>
    </ui-gmap-window>
    </ui-gmap-markers>
  </ui-gmap-google-map>
</div>

map-controller.js

projectControllers.controller('mapCtrl', function($scope, uiGmapGoogleMapApi, uiGmapIsReady){
uiGmapGoogleMapApi.then(function (maps) {
        //$scope.googlemap = {};
        $scope.map = {
            center: {
                latitude: 40.1451,
                longitude: -99.6680
            },
            zoom: 4,
            pan: 1,
            options: $scope.mapOptions,
            control: {},
            events: {
                tilesloaded: function (maps, eventName, args) {},
                dragend: function (maps, eventName, args) {},
                zoom_changed: function (maps, eventName, args) {}
            }
        };
    });
    $scope.options = {scrollwheel: false};
    $scope.marker = {
        title: 'Address',
        address: "",
        coords: {
            latitude: 40.1451,
            longitude: -99.6680
        },
        visible: false,
        id: 0
    };
    $scope.windowOptions = {
        show:false
    };

    $scope.onClick = function (data) {
        console.log(data);
        $scope.windowOptions.show = !$scope.windowOptions.show;
        console.log('$scope.windowOptions.show: ', $scope.windowOptions.show);
        console.log('Office Name ' + data);
        //alert('This is a ' + data);
    };
    $scope.info = "Bug! Info issue"; // Trying to set in onclick, but it doesn't reflect


    $scope.closeClick = function () {
        $scope.windowOptions.show = false;
    };

    uiGmapIsReady.promise() // if no value is put in promise() it defaults to promise(1)
        .then(function (instances) {
            console.log(instances[0].map); // get the current map
        })
        .then(function () {
            $scope.markers = [];
            for (var i = 0; i < $scope.addresses.length; i++) {
                $scope.markers.push({
                    id: $scope.markers.length,
                    coords: {
                        latitude: $scope.addresses[i].lat,
                        longitude: $scope.addresses[i].lng
                    },
                    data: $scope.addresses[i].name
                });
            }
            $scope.addMarkerClickFunction($scope.markers);
        });

    $scope.addMarkerClickFunction = function (markersArray) {
        angular.forEach(markersArray, function (value, key) {
            console.log(value);
            value.onClick = function () {
                $scope.info = value.data; //Doesn't seem to take the value here
                $scope.onClick(value.data);
                $scope.MapOptions.markers.selected = value;
            };
        });
    };
    $scope.MapOptions = {
        minZoom: 3,
        zoomControl: false,
        draggable: true,
        navigationControl: false,
        mapTypeControl: false,
        scaleControl: false,
        streetViewControl: false,
        disableDoubleClickZoom: false,
        keyboardShortcuts: true,
        markers: {
            selected: {}
        },
        styles: [{
            featureType: "poi",
            elementType: "labels",
            stylers: [{
                visibility: "off"
            }]
        }, {
            featureType: "transit",
            elementType: "all",
            stylers: [{
                visibility: "off"
            }]
        }],
    };



});

Solution

  • There are some issues in the provided example:

    1) $scope.markers needs to be declared before uiGmapIsReady service promise is getting resolved otherwise MarkersParentModel: no valid models attribute found or Cannot read property 'gManager' of undefined errors usually occur

    2) Apparently the expression {{mapCtrl.info}} is not valid since there is such scope property initialized as $scope.mapCtrl.info

    3)The proper expression syntax for click property of ui-gmap-markers directive is click="onClick" but not click="'onClick'" (at least in version 2 of angular-google-maps library)

    4) in most cases there is no need to create info window instance per every marker, so you could replace

    <ui-gmap-markers models="markers" idkey="markers.id" coords="'coords'" click="'onClick'" fit="true" events="markers.events">
         <ui-gmap-window coords="MapOptions.markers.selected.coords" show="windowOptions.show"  options="windowOptions" closeClick="closeClick()">
            <div>{{info}}</div>
        </ui-gmap-window>
    </ui-gmap-markers> 
    

    with

     <ui-gmap-window coords="MapOptions.markers.selected.coords" show="windowOptions.show"  options="windowOptions" closeClick="closeClick()">
            <div>{{info}}</div>
    </ui-gmap-window>
    <ui-gmap-markers models="markers" idkey="markers.id" coords="'coords'" click="'onClick'" fit="true" events="markers.events">
    </ui-gmap-markers>
    

    Example

    The following minimal example demonstrates how to display info window on marker click

    var app = angular.module('app', ['uiGmapgoogle-maps']);
    
    
    app.controller('mapCtrl', function ($scope, uiGmapGoogleMapApi, uiGmapIsReady) {
    
        $scope.markers = [];
        $scope.addresses = [
          {name: 'London',lat: 51.518305,lng: -0.130444},
          {name: 'Paris',lat: 48.856127,lng: 2.352362},
          {name: 'Madrid',lat: 40.431598,lng: -3.704263}
        ];
    
        $scope.map = {
            center: {
                latitude: 40.1451,
                longitude: -99.6680
            },
            zoom: 10
        };
    
        $scope.windowOptions = {
            show: false
        };
    
        $scope.onClick = function (marker, eventName, model) {
            $scope.windowOptions.show = !$scope.windowOptions.show;
            $scope.selectedCoords = model.coords;
            $scope.info = model.data;
        };
    
         $scope.closeClick = function () {
            $scope.windowOptions.show = false;
        };
    
    
    
        uiGmapIsReady.promise() 
            .then(function () {
                for (var i = 0; i < $scope.addresses.length; i++) {
                    $scope.markers.push({
                        id: $scope.markers.length,
                        coords: {
                            latitude: $scope.addresses[i].lat,
                            longitude: $scope.addresses[i].lng
                        },
                        data: $scope.addresses[i].name
                    });
                }
            });
       
    });
    .angular-google-map-container {
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        left: 0;
    }
    <script src="https://code.angularjs.org/1.3.14/angular.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
    <script src="http://rawgit.com/angular-ui/angular-google-maps/2.0.X/dist/angular-google-maps.js"></script>
    <div ng-app="app" ng-controller="mapCtrl">
                <ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="options" bounds="map.bounds">
                    <ui-gmap-window coords="selectedCoords" show="windowOptions.show"  closeclick="closeClick()">
                            <div>{{info}}</div>
                        </ui-gmap-window>
                    <ui-gmap-markers models="markers" idkey="markers.id" coords="'coords'" click="onClick" events="markersEvents"  fit="true" >
                    </ui-gmap-markers>
                </ui-gmap-google-map>
    </div>

    Plunker