6
votes

I am trying to load a map by using leaflet. when i refresh the map, I get the above error. I studied other proposed answers for this question. But, non of them worked for me. I am trying to load a map inside a function which is run by a onclick event. Here is the code:

function load_map_and_analyze_data(){
var mymap = L.map('mapid',{ center: new L.LatLng(the_center_splitted[0],the_center_splitted[1]),maxZoom: 17, minZoom:11, zoom: 14}); //creating the map
//the rest of analyze and code goes here
}

The tested proposed answers:
1- Check if my map is initialized, if yes remove it, and define it once again.

console.log(mymap);
if(mymap != 'undefined' || mymap != null) {
 mymap.remove(); 
} 

Result: mymap is undefined whenever i refresh the function and just the same error.
2- Defining this variable as a general variable outside of function just when mapdiv dom is ready. then i used jquery.

$( "#mapid" ).load(function() {
  var mymap= L.map('mapid');
});

Result: this error: Map container not found.
3- Removing the mydiv dom and just trying to recreate it inside of the function.

console.log(mymap);
if(mymap != undefined || mymap != null){
    mymap.remove();
   $("#mapdiv").html("");
   $( "<div id=\"mapdiv\" style=\"height: 500px;\"></div>" ).appendTo(document);
}

Result: mymap is undefined and just the code has not run to test its efficiency.
Any idea or suggestion is appreciated. Thank you.

2

2 Answers

9
votes

I have a suggestion that you need to create a reference in outer scope of a function you use to instantiate a Leaflet map. For example, you have a function

function load_map_and_analyze_data(){
  var mymap = L.map('mapid',{ center: new L.LatLng(the_center_splitted[0],the_center_splitted[1]),maxZoom: 17, minZoom:11, zoom: 14}); //creating the map
  //the rest of analyze and code goes here
}

that encapsulates mymap in it. After you execute this function, you have no chance to access the instance of Leaflet you just created. Any reference to mymap outside of this function's scope will refer to another variable. So, the idea is to keep this variable outside of the scope of this function:

var mymap = null;

function load_map_and_analyze_data() {
  mymap = L.map('mapid',{ center: new L.LatLng(the_center_splitted[0],the_center_splitted[1]),maxZoom: 17, minZoom:11, zoom: 14}); //creating the map
  //the rest of analyze and code goes here
}

Now, you can refer to mymap from anywhere within the scope this variable is defined. If it is the global scope, then you're not limited in it.

Next, do

console.log(mymap); // should output the object that represents instance of Leaflet
if (mymap !== undefined && mymap !== null) {
  mymap.remove(); // should remove the map from UI and clean the inner children of DOM element
  console.log(mymap); // nothing should actually happen to the value of mymap
}

and see if it works.

Don't forget that if you declare a new variable with the same name as in outer scope of a function, it's a new variable with a new reference, so you will not be able to refer to the variable in outer scope anymore. So be careful with vars.

1
votes

https://www.designlimbo.com/leaflet-ionic-3-and-map-container-is-already-initialized/

Dug hours through SO and Google and found the above to be the only method to work reliably. No messing with remove() or off().

A tiny bit of fiddling with ViewChild / ViewChildren to get DOM references but all my maps load reliably on any page no matter how the pages transition.

Hope this helps someone.