1

I am using Leaflet in my Ionic 2 app. When running the app first time. Everyhting is fine. But if I go to another page and back to the map I get the following exception:

EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error in build/pages/map/map.html:12:18 ORIGINAL EXCEPTION: Error: Map container is already initialized. ORIGINAL STACKTRACE: Error: Map container is already initialized.

The private variable map is null when coming back to this page. Checking this variable for beeing null has no effect because I think the problem is the new L.Map('mainmap',...

export class MainMapComponent {

  private map;

  constructor(
    private mapService: MapService,
    private geoCodingService: GeocodingService) { }

  ngOnInit() {
    console.log(this.map);
    if( this.map == null ) this.initMap();
  }

  initMap() {
    console.log('init');
    if(this.map) this.map.remove();
    this.map = new L.Map('mainmap', {
      zoomControl: false,
      center: new L.LatLng(40.731253, -73.996139),
      zoom: 12,
      minZoom: 4,
      maxZoom: 19,
      layers: [this.mapService.baseMaps.OpenStreetMap],
      attributionControl: false
    });
    console.log(this.map);
  }

}
rakete
  • 2,953
  • 11
  • 54
  • 108
  • What is the code of the template associated with your component? And where is your `mainmap` located? In your component template? Thanks! – Thierry Templier Aug 08 '16 at 15:17

2 Answers2

4

Probably not the most elegant solution but what worked for me is removing the map when the user leaves the view:

ionViewCanLeave(){
    document.getElementById("mainmap").outerHTML = "";
}

Source: https://forum.ionicframework.com/t/map-container-is-already-initialized-error-in-ionic-2/81666

3

The if( this.map == null ) condition in your ngOnInit() is always true, since when you instantiate a new MainMapComponent, that new instance will get its own brand new this.map, therefore unassigned (i.e. undefined) yet.

This is totally different from what may have happened to your "mainmap" div container.

To be more inline with your problem description, when navigating away from your map, your "mainmap" div container still holds a map. When coming back to your page, it looks like your app instantiates a new MainMapComponent instance, which has a new (unassigned yet) this.map, therefore it tries to initialize a new map in "mainmap" div container. This is what creates the error.

You could try to use this.map.remove() when your MainMapComponent instance is destroyed, so that the "mainmap" div status is in par with the existence (or not) of an instance of MainMapComponent. But that would not solve your problem if for any reason you have more than one instance of MainMapComponent at the same time.


Update:

As for the last mentioned issue, see Initializing leaflet map in angular2 component after DOM object exists

Community
  • 1
  • 1
ghybs
  • 47,565
  • 6
  • 74
  • 99
  • I don't instantiate more than one MainMapComponents but in onInit() it's calling the new L.Map() on the same div again. I don't know how to check, if a DOM-element is already initialized with a map. – rakete Aug 08 '16 at 16:22
  • Simply look for possible child nodes that would be already added by another Leaflet instantiation… – ghybs Aug 08 '16 at 16:27
  • No, I am sure that it's the instance of my first ngOnInit(). But how to get the intsance back to my this.map var? – rakete Aug 08 '16 at 19:39
  • Not sure I understand your above comment… :-S Rather than checking `this.map == null` (which is probably always `true`), you could try something like `document.getElementById("mainmap").firstNode` for example. But that may break your code as it might really need somehow to instantiate twice your component (you do not provide any context nor proof of what you think is sure, so who knows?..) – ghybs Aug 08 '16 at 20:02
  • I added more details specific to your problem description. – ghybs Aug 08 '16 at 20:57