Angular Leaflet - Map does does not render properly
Asked Answered
I

3

8

No matter which way I try in Angular 7, my Leaflet Map does not load properly. I get a block puzzle with half the screen grey and the other half in random disjointed map blocks (see pic).

Map Block Puzzle:


My HTML has been either:

<div 
  leaflet 
  [leafletOptions]="options">
</div>

or

<div id="map" class="map"></div>


My component is:

import * as L from "leaflet";
...
@Component( {
  styleUrls:  [ "../../../../node_modules/leaflet/dist/leaflet.css" ],
  templateUrl:  "./map.html"
} )
...
export class Map implements OnInit {

  map: any;

  options = {
    layers: [
        L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 7, attribution: '...' })],
        zoom: 5,
        center: L.latLng([ 46.879966, -121.726909 ])};

  async ngOnInit() {

    this.map =  L.map('map').setView( [37.8, -96], 4 );
    var osmUrl    = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
    var osmAttrib = 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
    var osm       = new L.TileLayer( osmUrl, { minZoom: 1, maxZoom: 7, attribution: osmAttrib } );      
    this.map.addLayer( osm ); // */

  }

} 

My app-module.ts has the "LeafletModule.forRoot()" added to the Imports. invalidateSize() did not work for me, though perhaps I used it wrong. I did it with a setTimeout and not, in a method call.

Am I missing something? Do I have to add a script to INDEX.HTML like this or something?

<script src="http://cdn.leafletjs.com/leaflet-0.4/leaflet.js"></script>

I have searched a lot of posts and followed tutorials, but nothing gets me a nice map loaded.

Can anyone help?

Thanks, Moa

Intersection answered 5/3, 2019 at 6:45 Comment(2)
I had the same problem time ago, just to be sure, once the map is loaded, resizing the browser page make the map load correctly?Conservator
When I resize the browser, the map is still gobbledegook. So invalidateSize() is not the issue.Intersection
F
9

Here are the steps you need to follow:

1.install leaflet and import leaflet css style on angular.json

"styles": ["../node_modules/leaflet/dist/leaflet.css", "styles.css"],

2.import leaflet in your ts:

import * as L from "leaflet";

3.initialize your map inside ngOnInit:

map;
ngOnInit() {
    this.map = L.map("map").setView([46.879966, -121.726909], 7);

    L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
          attribution:
            '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(this.map);
}

Demo

You do not need to use script & cdns since you import the files directly from the local folder. Plus you were trying to use leaflet 0.4 which is really obsolete version

Fribourg answered 5/3, 2019 at 8:45 Comment(7)
Question: My Angular project is with styles of SCSS. Could that be an issue?Intersection
Not at all. You just need to import leaflet.css styles on angular.json so that the map is rendered as expected. Check the demo. Please accept the answer if it helped you.Fribourg
Ok, I'm quite a few hours away from adding it, but will try to add it to my angular.json. But it will look like this for me: "styles": ["../node_modules/leaflet/dist/leaflet.css", "styles.scss"],. Notice that the styles is SCSS. Is that ok?Intersection
leaflet.css is the file which comes from leaflet's styles, the library. styles.scss is the angular root styles which is configured by the user to be used in the entire angular app. Similarly in components. There is no conflict between the two. If you also use other libraries like for instance font-awesome you can import its .css file with no conflict.Fribourg
It did work, yes!! But one thing was not mentioned, though perhaps because I'm no expert, it wasn't needed. When you add the "./node_modules/leaflet/dist/leaflet.css" to your angular.js RESTART your project! npm start was what I was missing. Thanks so much.Intersection
@Intersection Thank you so much, npm start saved me. I thought I was going crazy over here!Bowman
@Intersection thank you. I was going crazy and this was the problem. Thank you very much. Your answer is usefulNalda
T
3

I am using Angular Cli: 9.1.1

Install leaflet by npm command in the console

npm i leaflet

Modify angular.json file like this

{
  ...
  "projects": {
    "project-name": {
      ...
      "architect": {
        "build": {
          ...
          "options": {
            ...
            "styles": [
              "./src/styles.scss",
              "./node_modules/leaflet/dist/leaflet.css"
            ],
            ...
          }
        }
      }
    }
  }
}

And finally Re-Run the project by ng serve

Tarbox answered 21/4, 2020 at 12:19 Comment(0)
D
0

This is due to css encapsulation in Angular.

Solution : use ViewEncapsulation.None option

import { ViewEncapsulation } from '@angular/core';

//...

@Component({
    styleUrls:  [ "../../../../node_modules/leaflet/dist/leaflet.css" ],
    templateUrl:  "./map.html"
    encapsulation: ViewEncapsulation.None
})

Note! ViewEncapsulation.None will make your component css available to your entire app. Be carful on side effects

By default angular uses the Emulated encapsulation. This applies an attribute to all the DOM elements in your component and adds that attribute to your css rules. Since the TileLayer (also other elements/markers) are being added manually after initialization of the component, custom styles will not be applied untill you set encapsulation to ViewEncapsulation.None.

See more details of ViewEncapsulation

Domesticity answered 30/12, 2023 at 13:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.