Google map only work on first time in ionic modal

I’m building a mobile app with ionic. In one of my mobile page, there is one icon, on clicking of which user’s profile need to appear inside an ionic modal window. Then in the profile, I’m also showing user’s working location using Google Map.

So, the problem is when I’m first time opening the modal everything working fine. But, once closing the modal window & re-open it, everything is working except google map.

I’m also not getting any kind of error in my browser console(using chrome remote debugging).

Then, again if I kill the app & re-open it, again it’s working for the first time but not for rest of the time.

Here is one screenshot when it’s working -

Here is another than when it’s not working-

My Modal window file -

	<ion-header-bar class="bar bar-header bar-positive">
		<button class="button remove-btn-border" ng-click="closeModal()">
			<i class="icon ion-android-arrow-back"></i>
		</button>
		<h1 class="title">Employee Profile</h1>
	</ion-header-bar>

	<ion-content>
		<div class="list card">

			<div class="item item-avatar">
				<img ng-src="{{baseUrl}}/{{empDetails.Profile_Img}}" >
				<h2>{{empDetails.Emp_Name}}</h2>
			</div>

			<div class="item item-body">

				<div class="item item-divider">
					<span style='font-weight:bold;'><i class="icon ion-android-call"></i></span>
					<span style='font-size:13px;'> &nbsp; {{empDetails.Number}}</span>
				</div>
				<div class="item item-text-wrap">
					<span style='font-weight:bold;'><i class="icon ion-email"></i></span>
					<span style='font-size:13px;'> &nbsp; {{empDetails.User_Email}}</span>
				</div>
				<div class="item item-divider">
					<span style='font-weight:bold;'><i class="icon ion-briefcase"></i></span>
					<span style='font-size:13px;'> &nbsp; {{empDetails.Employment_Type}}/{{empDetails.Employment_Status}}</span>
				</div>
				<div class="item item-text-wrap">
					<span style='font-weight:bold;'>Designation</span><br>
					<span style='font-size:13px;'>{{empDetails.Designation_Id}}</span>
				</div>
				<div class="item item-divider item-text-wrap">
					<span style='font-weight:bold;'>Location</span><br>
					<span style='font-size:13px;'>{{empDetails.Location_Address}}</span>
				</div>

				<div class="item item-text-wrap" id="map" data-tap-disabled="true">
					Google map place holder
				</div>
			</div>

			<div class="item tabs tabs-secondary tabs-icon-left" style="background:#F8F8F8;">

				<a class="tab-item" ng-href="tel:{{empDetails.Number}}" style="color:#9E9D9D;">
					<i class="icon ion-android-call"></i>Call
				</a>

				<a class="tab-item" ng-href="mailto:{{empDetails.User_Email}}" style="color:#9E9D9D;">
					<i class="icon ion-email"></i>Send email
				</a>
			</div>

		</div>
	</ion-content>

</ion-modal-view>

My Controller file -

angular.module('app.HomeController', [])

// Employee Attendance Controller
.controller('HomeController', function($scope, $state, $location, $ionicHistory, $ionicSideMenuDelegate, $ionicModal, $ionicLoading, $cordovaNetwork, $http, $ionicPopup, UserService, GeoAlert){

    console.log('Inside Home Controller');

    var baseUrl=null;

    $scope.openModal = function() {
        $scope.modal.show();
    };

    $scope.closeModal = function() {
        console.log('Clicked on Cancel modal button');
        $scope.modal.hide();
    };

    //Cleanup the modal when we're done with it!
    $scope.$on('$destroy', function() {
        $scope.modal.remove();
    });

    // Execute action on hide modal
    $scope.$on('modal.hidden', function() {
        // Execute action
        $scope.$on('$destroy', function () {
            $scope.map = null;
        });
    });

    // Execute action on remove modal
    $scope.$on('modal.removed', function() {
    // Execute action
    });


    $http.get('js/config.json')
        .then(function(res){
            baseUrl = res.data.server[res.data.mode];
            $scope.baseUrl = baseUrl;
        });


    // Method for showing employee profile page
    $scope.showEmpSelfProfile = function(){
        console.log('Clicked on showEmpSelfProfile icon from Home.js Controller file');

        $ionicModal.fromTemplateUrl('templates/emp-profile/empProfile.html', {
            scope: $scope,
            animation: 'slide-in-up'
        }).then(function(modal) {
            $scope.modal = modal;
            $scope.modal.show();
        });


        // Show spinner animation
        $ionicLoading.show({
            template: '<ion-spinner icon="android"></ion-spinner>'
        });

        // Make ajax call to server for fetching employee details
        var postData = {
                empId:window.localStorage.getItem('user_id'),
                session_id:window.localStorage.getItem('session_id'),
                data_type:'empProfile',
            };

        $http({
            method: 'POST',
            url: baseUrl+'/S/E2Pro_ASL_M_FetchDataSet.php',
            data : postData
        }).then(function successCallback(response) {

            if(response['data']['status'] === 'success'){
                $scope.empDetails = response['data']['data'];
                orgGeoCoordinates = response['data']['data']['Org_GeoCoordinates'];

                // Showing gmap in profile details page
                console.log('orgGeoCoordinates details after ajax call : '+orgGeoCoordinates);

                if(orgGeoCoordinates.lat && orgGeoCoordinates.lng)
                {
                    var myLatlng = new google.maps.LatLng(orgGeoCoordinates.lat, orgGeoCoordinates.lng);

                    var mapOptions = {
                        center: myLatlng,
                        zoom: 20,
                        mapTypeId: google.maps.MapTypeId.ROADMAP
                    };

                    $scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);

                    google.maps.event.addListenerOnce($scope.map, 'idle', function () {

                        var marker = new google.maps.Marker({
                            map: $scope.map,
                            animation: google.maps.Animation.DROP,
                            position: myLatlng
                        });
                    });

                    console.log('Google map going to plot');
                }
            }

            if(response['data']['status'] === 'error'){
                if(response['data']['message'] === 'User session dose not exist')
                {
                    UserService.reInitializeSession();
                }
            }

            // Remove loading animation
            $ionicLoading.hide();

        }, function errorCallback(response) {
            // Remove loading animation
            $ionicLoading.hide();
        });


    }

});

I’m building a mobile app with ionic. In one of my mobile page, there is one icon, on clicking of which user’s profile need to appear inside an ionic modal window. Then in the profile, I’m also showing user’s working location using Google Map.

So, the problem is when I’m first time opening the modal everything working fine. But, once closing the modal window & re-open it, everything is working except google map.

I’m also not getting any kind of error in my browser console(using chrome remote debugging).

Then, again if I kill the app & re-open it, again it’s working for the first time but not for rest of the time.

Here is one screenshot when it’s working -

enter image description here

Here is another than when it’s not working-

enter image description here

My Modal window file -

<ion-header-bar class="bar bar-header bar-positive">
    <button class="button remove-btn-border" ng-click="closeModal()">
        <i class="icon ion-android-arrow-back"></i>
    </button>
    <h1 class="title">Employee Profile</h1>
</ion-header-bar>

<ion-content>
    <div class="list card">

        <div class="item item-avatar">
            <img ng-src="{{baseUrl}}/{{empDetails.Profile_Img}}" >
            <h2>{{empDetails.Emp_Name}}</h2>
        </div>

        <div class="item item-body">

            <div class="item item-divider">
                <span style='font-weight:bold;'><i class="icon ion-android-call"></i></span>
                <span style='font-size:13px;'> &nbsp; {{empDetails.Number}}</span>
            </div>
            <div class="item item-text-wrap">
                <span style='font-weight:bold;'><i class="icon ion-email"></i></span>
                <span style='font-size:13px;'> &nbsp; {{empDetails.User_Email}}</span>
            </div>
            <div class="item item-divider">
                <span style='font-weight:bold;'><i class="icon ion-briefcase"></i></span>
                <span style='font-size:13px;'> &nbsp; {{empDetails.Employment_Type}}/{{empDetails.Employment_Status}}</span>
            </div>
            <div class="item item-text-wrap">
                <span style='font-weight:bold;'>Designation</span><br>
                <span style='font-size:13px;'>{{empDetails.Designation_Id}}</span>
            </div>
            <div class="item item-divider item-text-wrap">
                <span style='font-weight:bold;'>Location</span><br>
                <span style='font-size:13px;'>{{empDetails.Location_Address}}</span>
            </div>

            <div class="item item-text-wrap" id="map" data-tap-disabled="true">
                Google map place holder
            </div>
        </div>

        <div class="item tabs tabs-secondary tabs-icon-left" style="background:#F8F8F8;">

            <a class="tab-item" ng-href="tel:{{empDetails.Number}}" style="color:#9E9D9D;">
                <i class="icon ion-android-call"></i>Call
            </a>

            <a class="tab-item" ng-href="mailto:{{empDetails.User_Email}}" style="color:#9E9D9D;">
                <i class="icon ion-email"></i>Send email
            </a>
        </div>

    </div>
</ion-content>

angular.module(‘app.HomeController’, )

// Employee Attendance Controller
.controller(‘HomeController’, function($scope, $state, $location, $ionicHistory, $ionicSideMenuDelegate, $ionicModal, $ionicLoading, $cordovaNetwork, $http, $ionicPopup, UserService, GeoAlert){

console.log('Inside Home Controller');

var baseUrl=null;

$scope.openModal = function() {
    $scope.modal.show();
};

$scope.closeModal = function() {
    console.log('Clicked on Cancel modal button');
    $scope.modal.hide();
};

//Cleanup the modal when we're done with it!
$scope.$on('$destroy', function() {
    $scope.modal.remove();
});

// Execute action on hide modal
$scope.$on('modal.hidden', function() {
    // Execute action
    $scope.$on('$destroy', function () {
        $scope.map = null;
    });
});

// Execute action on remove modal
$scope.$on('modal.removed', function() {
// Execute action
});


$http.get('js/config.json')
    .then(function(res){
        baseUrl = res.data.server[res.data.mode];
        $scope.baseUrl = baseUrl;
    });


// Method for showing employee profile page
$scope.showEmpSelfProfile = function(){
    console.log('Clicked on showEmpSelfProfile icon from Home.js Controller file');

    $ionicModal.fromTemplateUrl('templates/emp-profile/empProfile.html', {
        scope: $scope,
        animation: 'slide-in-up'
    }).then(function(modal) {
        $scope.modal = modal;
        $scope.modal.show();
    });


    // Show spinner animation
    $ionicLoading.show({
        template: '<ion-spinner icon="android"></ion-spinner>'
    });

    // Make ajax call to server for fetching employee details
    var postData = {
            empId:window.localStorage.getItem('user_id'),
            session_id:window.localStorage.getItem('session_id'),
            data_type:'empProfile',
        };

    $http({
        method: 'POST',
        url: baseUrl+'/S/E2Pro_ASL_M_FetchDataSet.php',
        data : postData
    }).then(function successCallback(response) {

        if(response['data']['status'] === 'success'){
            $scope.empDetails = response['data']['data'];
            orgGeoCoordinates = response['data']['data']['Org_GeoCoordinates'];

            // Showing gmap in profile details page
            console.log('orgGeoCoordinates details after ajax call : '+orgGeoCoordinates);

            if(orgGeoCoordinates.lat && orgGeoCoordinates.lng)
            {
                var myLatlng = new google.maps.LatLng(orgGeoCoordinates.lat, orgGeoCoordinates.lng);

                var mapOptions = {
                    center: myLatlng,
                    zoom: 20,
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                };

                $scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);

                google.maps.event.addListenerOnce($scope.map, 'idle', function () {

                    var marker = new google.maps.Marker({
                        map: $scope.map,
                        animation: google.maps.Animation.DROP,
                        position: myLatlng
                    });
                });

                console.log('Google map going to plot');
            }
        }

        if(response['data']['status'] === 'error'){
            if(response['data']['message'] === 'User session dose not exist')
            {
                UserService.reInitializeSession();
            }
        }

        // Remove loading animation
        $ionicLoading.hide();

    }, function errorCallback(response) {
        // Remove loading animation
        $ionicLoading.hide();
    });


}

});
My Controller file -

angular.module(‘app.HomeController’, )

// Employee Attendance Controller
.controller(‘HomeController’, function($scope, $state, $location, $ionicHistory, $ionicSideMenuDelegate, $ionicModal, $ionicLoading, $cordovaNetwork, $http, $ionicPopup, UserService, GeoAlert){

console.log('Inside Home Controller');

var baseUrl=null;

$scope.openModal = function() {
    $scope.modal.show();
};

$scope.closeModal = function() {
    console.log('Clicked on Cancel modal button');
    $scope.modal.hide();
};

//Cleanup the modal when we're done with it!
$scope.$on('$destroy', function() {
    $scope.modal.remove();
});

// Execute action on hide modal
$scope.$on('modal.hidden', function() {
    // Execute action
    $scope.$on('$destroy', function () {
        $scope.map = null;
    });
});

// Execute action on remove modal
$scope.$on('modal.removed', function() {
// Execute action
});


$http.get('js/config.json')
    .then(function(res){
        baseUrl = res.data.server[res.data.mode];
        $scope.baseUrl = baseUrl;
    });


// Method for showing employee profile page
$scope.showEmpSelfProfile = function(){
    console.log('Clicked on showEmpSelfProfile icon from Home.js Controller file');

    $ionicModal.fromTemplateUrl('templates/emp-profile/empProfile.html', {
        scope: $scope,
        animation: 'slide-in-up'
    }).then(function(modal) {
        $scope.modal = modal;
        $scope.modal.show();
    });


    // Show spinner animation
    $ionicLoading.show({
        template: '<ion-spinner icon="android"></ion-spinner>'
    });

    // Make ajax call to server for fetching employee details
    var postData = {
            empId:window.localStorage.getItem('user_id'),
            session_id:window.localStorage.getItem('session_id'),
            data_type:'empProfile',
        };

    $http({
        method: 'POST',
        url: baseUrl+'/S/E2Pro_ASL_M_FetchDataSet.php',
        data : postData
    }).then(function successCallback(response) {

        if(response['data']['status'] === 'success'){
            $scope.empDetails = response['data']['data'];
            orgGeoCoordinates = response['data']['data']['Org_GeoCoordinates'];

            // Showing gmap in profile details page
            console.log('orgGeoCoordinates details after ajax call : '+orgGeoCoordinates);

            if(orgGeoCoordinates.lat && orgGeoCoordinates.lng)
            {
                var myLatlng = new google.maps.LatLng(orgGeoCoordinates.lat, orgGeoCoordinates.lng);

                var mapOptions = {
                    center: myLatlng,
                    zoom: 20,
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                };

                $scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);

                google.maps.event.addListenerOnce($scope.map, 'idle', function () {

                    var marker = new google.maps.Marker({
                        map: $scope.map,
                        animation: google.maps.Animation.DROP,
                        position: myLatlng
                    });
                });

                console.log('Google map going to plot');
            }
        }

        if(response['data']['status'] === 'error'){
            if(response['data']['message'] === 'User session dose not exist')
            {
                UserService.reInitializeSession();
            }
        }

        // Remove loading animation
        $ionicLoading.hide();

    }, function errorCallback(response) {
        // Remove loading animation
        $ionicLoading.hide();
    });


}

});

Any guess, what’s could be the problem.

Regards

I am having the same problem with Ionic 2. I read that you need to resize and recenter the map after you have loaded it. This may fix it.

I’m seeing a simular issue where I nav.push the map page, I can see the map fine, I navigate back and the map fails to load… I have a ViewChild reference, “mapElement”, that become undefined during this process of navigation…

...
@Component({
  selector: 'page-map',
  templateUrl: 'map.html'
})
export class MapPage {
  @ViewChild('map') mapElement;
  map: any;
  mapInitialized: boolean = false;
...

My console.log message showing the element is undefined: “mapElement is undefined”

Any thoughts??

Add this : cache: false to your state provider (when you defined your map). This worked for me.