It shows black screen when trying to load Map on device with ionic 2 Google Map Native plugin


screenshot of the error

Note This project must be run on a device, iOS or Andriod

Background:

I had installed the native google maps plugin into my ionic 2 project using the command $ ionic plugin add cordova-plugin-googlemaps --variable API_KEY_FOR_ANDROID="YOUR_ANDROID_API_KEY_IS_HERE" --variable API_KEY_FOR_IOS="YOUR_IOS_API_KEY_IS_HERE" as shown in the following link: http://ionicframework.com/docs/v2/native/google-maps/

Then i'd run the command $ ionic platform add ios and then $ ionic build ios

Everything goes as expected till this point. When i try to display a map, i see a black screen, don't know whats missing!

Code:

/src/app/app.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';

import { HomePage } from '../pages/home/home';

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}]
})
export class AppModule {}

/src/app/app.component.ts

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';

import { HomePage } from '../pages/home/home';

import {
  GoogleMap,
  GoogleMapsEvent,
  GoogleMapsLatLng,
  CameraPosition,
  GoogleMapsMarkerOptions,
  GoogleMapsMarker
  // GoogleMapsMapTypeId
} from 'ionic-native';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage = HomePage;

  constructor(platform: Platform) {
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();
      Splashscreen.hide();

      let map = new MapPage();
      map.loadMap();
    });
  }
}

class MapPage {
  constructor() {}

// Load map only after view is initialize
  ngAfterViewInit() {
    this.loadMap();
  }

  loadMap() {
    // make sure to create following structure in your view.html file
    // and add a height (for example 100%) to it, else the map won't be visible
    // <ion-content>
    //  <div #map id="map" style="height:100%;"></div>
    // </ion-content>

    // create a new map by passing HTMLElement
    let element: HTMLElement = document.getElementById('map');

    let map = new GoogleMap(element);

    // create LatLng object
    let ionic: GoogleMapsLatLng = new GoogleMapsLatLng(43.0741904,-89.3809802);

    // create CameraPosition
    let position: CameraPosition = {
      target: ionic,
      zoom: 18,
      tilt: 30
    };

    // listen to MAP_READY event
    map.one(GoogleMapsEvent.MAP_READY).then(() => {
      // move the map's camera to position
      map.moveCamera(position); // works on iOS and Android
    });


    // create new marker
    let markerOptions: GoogleMapsMarkerOptions = {
      position: ionic,
      title: 'Ionic'
    };

    map.addMarker(markerOptions)
        .then((marker: GoogleMapsMarker) => {
          marker.showInfoWindow();
        });
  }
}

/src/pages/home/home.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <div #map id="map" style="height:100%;"></div>
</ion-content>

Could someone please help in figuring out the problem. Your help is deeply appreciated.

Link to documentation

Link to project repo


Answers:


let map = new MapPage();
  map.loadMap();`

MapPage is a plain typescript class. It is not a component and it wont run lifecycle hooks like this:

 ngAfterViewInit() {
    this.loadMap();
  }

Also the call map.loadMap() in App.html is not working because your element is in home component.

I suggest you move map related code to home component. Also use viewChild to get the map div which would be an ElementRef object.

Home Component

  constructor() {}
@ViewChild('map')
  private mapElement: ElementRef;

// Load map only after view is initialize
  ngAfterViewInit() {
    this.loadMap();
  }

  loadMap() {

    let map = new GoogleMap(this.mapElement.nativeElement);

   //...etc etc
  }
}

Angular Documentation Reference: https://angular.io/docs/ts/latest/guide/