Igor-Vladyka / leaflet.browser.print

A leaflet plugin which allows users to print the map directly from the browser
https://igor-vladyka.github.io/leaflet.browser.print/
MIT License
155 stars 76 forks source link

[SOLVED] Error: Map container is already initialized at AngularJS state provider #83

Closed mujie-dm closed 4 years ago

mujie-dm commented 4 years ago

Hi, I've 2 pages build with AngularJS and bootstrap, one page for the leafletjs map + leaflet.browser.print plugin, another one is for manage user profile. To switch between the pages, I used AngularJS's state provider.

When I switch to profile page with state provider and switch back to the leafletjs map, I can't print out the map. It said "Error: Map container is already initialized". But it work if I'm not switch the state to profile page after map load first.

This the shortcut codes for print function:

    $(document).ready(function() {
      $(document).on("click","#map-print",function() {
        var printMap = L.control.browserPrint.mode.landscape();
        mymap.printControl.print(printMap);
      });
    })

I try to follow links below, but still no luck: https://stackoverflow.com/questions/19186428/refresh-leaflet-map-map-container-is-already-initialized https://stackoverflow.com/questions/40825987/leaflet-map-container-is-already-initialized-does-not-get-solved-by-proposed-a

Thank you for suggest and help. Regards, M

Igor-Vladyka commented 4 years ago

Hi,

I'm not sure what is going on in your code, but as a suggestion(if I understand it correctly), you can try to rename your "#map-print" button to something different. When we print a map in browser-print plugin we create overlay over current page, with an id from your map container + suffix("-print"). In case your map container id is just "map" then overlay container will be "map-print"(yeah, will change it in next major release) and in this case you can end up with a conflic if you have any control with a same name already.

Regards, Igor

mujie-dm commented 4 years ago

@Igor-Vladyka thanks for your quick reply, it seems AngularJS fault.

var container = L.DomUtil.get('map-print');
console.log(container);

From there I can see every time I switch repeatedly to another page and return to the map, then the map-print ID div will increase.

Regards, M

Igor-Vladyka commented 4 years ago

This is kinda strange. How it's increasing, like adding number to the end? Try changing container names and/or track HTML via chrome/elements tab events(to get and idea when and from where they are created. There is a chance that somewhere inside AngularJS your factory triggers multiple times when you navigate back and forth.

Also, please let me know if you need more tips or just close the ticket if not.

Best wishes, Igor

mujie-dm commented 4 years ago

No, this will copy the same DIV to the end as much as I moved pages. Example: <div id="map-print"></div> After switch to another page and back to the map, it will be like

<div id="map-print"></div>
<div id="map-print"></div>

I stil try to figure out, It doesn't matter if the case is closed.

Regards, M

mujie-dm commented 4 years ago

Hi, it's me again. I think I found a dirty way to cure this problem. On AngularJS I'm use routeChangeSuccess and routeChangeStart also change ui.router module to ng-route module to prevent multiply DOM reload behind. The point is, refresh other pages where the leaflet isn't displayed.

There is the snippet codes at my AngularJS controller


//after successfull switch page to the profile page
  $rootScope.$on("$routeChangeSuccess", function($event, next, current) { 
    $(document).ready(function(){ 
      if (current.originalPath == '/map') { //if leave a leafletJS map page
        $("#userprofile").remove(); //remove the user profile div ID first for prevent flicker
        $window.location.reload(); //reload the user profile page
      }
    });      
  });

//in case if user profile div ID not remove before we switch to profile page
  $rootScope.$on("$routeChangeStart", function($event, next, current) { 
    if (next.originalPath == '/user/profile') {
      $("#userprofile").remove();
    } 

Hopefully this can help others. If there are other additions, please comment. Thank you for your time.

Regards, M