Angluar Google Maps does not work with Caching turned on


#1

I am using Ionic (beta 14) and the Angular Google Maps plugin - http://angular-ui.github.io/angular-google-maps/

It all works fine, except if I go into a detail page and return to the map view, blocks of the page sometimes do not render correctly if page caching is on and the user drags the map. If I turn caching off then it works better, however I wanted to take advantage of caching.

e.g.
<ion-view view-title="Poker Game Map" cache-view="false">

Anyone else experiencing the same result?

Update: Upgraded to RC 1.02 and same result


#2

Hmmm - after a lot more testing it does not seem to be the Angular caching - it does the same thing with Caching on or off… I have also upgraded to the latest Angular-google-maps version with no joy


#3

any updates on that? Im having the same trouble, the map is not keeping the markers and stuff, it just goes away after a change of view.


#4

No, it is still a major issue unfortunately…


#5

Can you paste your code here? I fixed this issue in my current app but i don’t remember what i did, but it is not a thing about the cache, its probably about the instantiation of the map element or something related.


#6

Thanks, here is the HTML:

<ion-view view-title="Poker Game Map" cache-view="true">
    <ion-content>
        <div data-tap-disabled="true">
            <ui-gmap-google-map id="GamesMap" draggable="true" options="map.options" control="map.control" center="map.center" zoom="map.zoom" events="map.events">
                <ui-gmap-markers doCluster="false" fit="false" models="markers" coords="'self'" events="markersEvents">
                </ui-gmap-markers>
            </ui-gmap-google-map>
        </div>
    </ion-content>
</ion-view>

and here is the JS

"use strict";

(function () {
    angular.module('pokerGameFinder.gamesMapCtrl', [])    

        .controller('GamesMapCtrl', function(findmylocation, $ionicPlatform, $log, $scope, $state, $cordovaKeyboard, gameadrepository, DeviceInfo, geocoder, appConfig, searchData, AnalyticsTracker, toastr, LoaderService) {
            $log.debug("GamesMapCtrl Controller loaded", searchData.getLocation())
            
            var lastLocation = null;
            
            //have to do this as Caching is on and much check if the search has changed every time it is shown again
            $scope.$on('$ionicView.beforeEnter', function() {
                $log.debug('beforeEnter');
                checkLocation();
            });
          
            //this is the first controller so it must wait until everything is loaded
            $ionicPlatform.ready(function() {
                //if I don't put this here it gets a wierd Google Maps error
                $scope.markers = [];            
            });
           
            $scope.findMyLocation = function() {
                findmylocation.getCurrentLocation()
                    .then(function(location) {
                        searchData.setLocation(location); 
                        $scope.addressText = searchData.getLocation().searchTerm;
                        centreMap(location);
                    }, function() {
                        //don't know why I have to put this here but it would not hide on iOS if not (does not fire in the error handler on the Service for some reason)
                        LoaderService.hide();
                    });
            }
            
            $scope.findAddress = function(address) {
                //abstract this into a service!
                //geocoder.geoCodeAddress(address);
                var geocoder = new google.maps.Geocoder();
               
                geocoder.geocode({ 'address': address}, function(results, status) {
                    $log.debug(address, results, status);
                    if (status === google.maps.GeocoderStatus.OK) {
                        var location = { searchTerm: address, latitude: results[0].geometry.location.lat(), longitude: results[0].geometry.location.lng(), milesRadius:50 };      
                        searchData.setLocation(location); 
                        
                        //this should close automatically on a submit but it does not (only do it if successful)
                        if (!DeviceInfo.isSimulator()) {
                            $cordovaKeyboard.close()
                        }
                        centreMap(location);
                    } else {
                        AnalyticsTracker.logError('findAddress - Could not geocode this address: ' + status);
                        toastr.show('Address not found - please try again');
                    }
                });
                return;
            };
            
            //abstract this to a helper class as it is used by Detail page too
            function centreMap(location) {
                $log.debug('Updating Map Center to ', location);
                
                $scope.map = {
                    center: {
                        latitude: location.latitude,
                        longitude: location.longitude
                    },
                    zoom: 9,   //if you change this then the MilesRadius changes!
                    options: {
                        maxZoom: 18,
                        //maybe until sort out the bounds/zoom issue
                        minZoom: 5
                    },
                    control: {},
                    events: {
                        tilesloaded: function (map) {
                            //was using the idle event but was firing when keyboard opened etc
                            $scope.$apply(function () {
                                //http://angular-ui.github.io/angular-google-maps/#!/faq
                                //   $log.debug('Map instance', map);
                                var milesRadius = 50;
                                
                                switch (map.zoom) {
                                    case 18:
                                    case 17:
                                    case 16:
                                        milesRadius = 1;
                                        break;
                                    case 15:
                                    case 14:
                                        milesRadius = 2;
                                        break;
                                    case 13:
                                        milesRadius = 3;
                                        break;
                                    case 12:
                                        milesRadius = 5;
                                        break;
                                    case 11:
                                        milesRadius = 15;
                                        break;
                                    case 10:
                                        milesRadius = 25;
                                        break;
                                    case 9:
                                        milesRadius = 50;
                                        break;
                                    case 7:
                                    case 8:
                                        milesRadius = 100;
                                        break;
                                    case 6:
                                        milesRadius = 400;
                                        break;
                                    case 5:
                                        milesRadius = 1000;
                                        break;
                                    case 4:
                                        milesRadius = 5000;
                                        break;
                                    case 3:
                                        milesRadius = 5000;
                                        break;
                                }
              
                                //get the games for this new location
                                //this used to be k and D... I have no idea why it changed - do not use this, use the below
                                //var centerlocation = { latitude: map.center.k, longitude: map.center.D, milesRadius: milesRadius };
                                var centerlocation = { latitude: map.center.lat(), longitude: map.center.lng(), milesRadius: milesRadius };
                                $log.debug('Map center location - zoom: ' + map.zoom, centerlocation);
                                
                                searchData.setLocation(centerlocation); 
                                lastLocation = searchData.getLocation();
                                $log.debug('lastLocation updated: ', lastLocation);
                                
                                loadGamesForLocation(centerlocation);
                            });
                        }
                    },
                    
                };   
            }    
            
            function checkLocation() {
                //center the map on the user's location if it has not been set yet
                //var location = $rootScope.searchLocation;
                var location = searchData.getLocation();
                
                $log.debug('lastLocation: ', lastLocation);
                
                if (searchData.getLocation() === null) {
                    findmylocation.getCurrentLocation()
                        .then(function(location) {
                            searchData.setLocation(location); 
                            centreMap(searchData.getLocation());
                            $scope.addressText = searchData.getLocation().searchTerm;
                        }, function(error) {
                            //could not get current location or was denied - so do no nothing and the user can type a location - enter the default location in case they go to the List page without searching
                            searchData.setLocation(appConfig.startingLocation);
                            centreMap(searchData.getLocation());
                            $scope.addressText = searchData.getLocation().searchTerm;
                            LoaderService.hide();
                        });
                } else {
                    if (searchData.getLocation() !== lastLocation) {
                        $log.debug('Last stored location updated', searchData.getLocation(), lastLocation);
                        centreMap(searchData.getLocation());
                        $scope.addressText = searchData.getLocation().searchTerm;
                    }
                }
            }
            
            function loadGamesForLocation(location) {
                //load the game for this location
                gameadrepository.getGamesForLocation(location)
                    .$promise.then(function(gameAds) {
                        $scope.gameAds = gameAds;
                        createMarkers();
                    });   
            }
                
            function createMarkers() {
                $log.debug('Creating Markers');
                
                var gameAdLocationMarkers = [];
                var n = 0;
                
                angular.forEach($scope.gameAds, function (gameAd) {
                    var marker = {
                        latitude: gameAd.Latitude,
                        longitude: gameAd.Longitude,
                        showWindow: false,
                        title: gameAd.Title,
                        id: gameAd.GameId,
                        hostUserID: gameAd.HostUserId
                    };

                    gameAdLocationMarkers.push(marker);
                    n += 1;
                });
                
                $scope.markers = gameAdLocationMarkers;
                $scope.markersEvents = {
                    click: function (gMarker, eventName, model) {
                        $state.go('app.tabs.gameDetail', {gameAdId: model.id, gameHostUserId: model.hostUserID});
                    }
                };
            }
        })
}());

#7

Could be because of transitions. try this piece of code in the controller of your map

$scope.$on("$ionicView.afterEnter", function(){
	$timeout(function() {
		$scope.map.control.refresh({latitude: location.latitude, longitude: location.longitude});	
	});
});