Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ionic - google maps not displaying (or showing grey)

I'm having a lot of trouble making google maps co-operate with the ionic framework. Here's an example where I followed this guide to get google maps to successfully work on index.html. However, when I try and add some new pages to the app and navigate between them, the map doesn't display properly unless you refresh the page.

I made 3 pages that are injected into index.html: Home, intermediary and office. Home is supposed to show google maps and link to intermediary. Intermediary is just an empty page that links to home and office. Office is also supposed to show a map and links back to home.

This is the behavior I get:

  • home -> intermediate -> office - the map doesn't show on office
  • home -> intermediate -> office -> home - the map is grey

Why is this happening? I've tried wrapping the google maps functionality with

google.maps.event.addDomListener(window, 'load', function() {});

and tried every solution I've found for "google maps javascript api grey screen" but nothing seems to work.

Here's the relevant source:

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
    <link href="css/ionic.app.css" rel="stylesheet">
    -->

    <!-- ionic/angularjs js -->
    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <!-- cordova script (this will be a 404 during development) -->
    <script src="cordova.js"></script>

    <!-- your app's js -->
    <script src="js/app.js"></script>
  </head>
  <body ng-app="starter">

    <ion-pane>
      <ion-header-bar class="bar-stable">
        <h1 class="title">Ionic Blank Starter</h1>
      </ion-header-bar>
      <ion-nav-view><!-- Other html files injected here --></ion-nav-view> 
    </ion-pane>
    <script src="http://maps.googleapis.com/maps/api/js?sensor=true"></script>
  </body>
</html>

app.js

// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
var example = angular.module('starter', ['ionic'])

.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }
  });
});


example.config(function($stateProvider, $urlRouterProvider) {

  $stateProvider
    .state('home', {
      url: "/home",
      templateUrl: "app/home/home.html"
    })
    .state('intermediate', {
      url: "/intermediate",
      templateUrl: "app/intermediate/intermediate.html"
    })
    .state('office', {
      url: "/office",
      templateUrl: "app/office/office.html"
    });

  $urlRouterProvider.otherwise("/home");
});

example.controller("MapController", function($scope, $ionicLoading) {

    //google.maps.event.addDomListener(window, 'load', function() {
        var myLatlng = new google.maps.LatLng(37.3000, -120.4833);

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

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

        //$scope.map = map;
    //});

});

style.css

/* Empty. Add your own CSS if you like */
.scroll {
    height: 100%;
}

#map {
    height: 100%;
    width: 100%;
}

home.html

<ion-view>

    <ion-content class="padding has-header" ng-controller="MapController">

    <h1>Home</h1>   
    <h1><a ui-sref="intermediate">Intermediate</a></h1>

    <div id="map" data-tap-disabled="true"></div>

    </ion-content>
</ion-view>

intermediate.html

<ion-view>

    <ion-content class="padding has-header" ng-controller="MapController">

    <h1>Intermediate</h1>
    <a ui-sref="home">Home</a>
    <a ui-sref="office">Office</a>

    </ion-content>
</ion-view>

office.html

<ion-view>

    <ion-content class="padding has-header" ng-controller="MapController">

    <h1>Office</h1>
    <h1><a ui-sref="home">Home</a></h1>

    <div id="map" data-tap-disabled="true"></div>

    </ion-content>
</ion-view>
like image 598
ericgrosse Avatar asked Dec 24 '22 15:12

ericgrosse


1 Answers

Because you have multiple map elements with the same ID. Javascript just doesn't allow that. I know they are separate pages, but with Ionic framework, the three pages are in one same DOM. When you switch to another page, Ionic will append ion-view to current DOM instead of rebuilding a whole new DOM. Ionic does this by default for better UI performance. To confirm this, you can switch between pages and use inspector to find id="map". You will find multiple results, and Javascript is not smart enough to determine which map to append the map html. To avoid this you can set cache to be false like this:

  $stateProvider
    .state('home', {
      url: "/home",
      cache: false,
      templateUrl: "app/home/home.html"
    })
    .state('intermediate', {
      url: "/intermediate",
      cache: false,
      templateUrl: "app/intermediate/intermediate.html"
    })
    .state('office', {
      url: "/office",
      cache: false,
      templateUrl: "app/office/office.html"
    });

Also for google map itself, you need to trigger a resize event to fix the grey-out. You need to have below code after you generate the map object:

google.maps.event.addListener(map, "idle", function(){
    google.maps.event.trigger(map, 'resize'); 
});
like image 168
Jaaaaaaay Avatar answered Jan 05 '23 13:01

Jaaaaaaay