Use Leaflet in your Angular 10 project for interactive maps

If you’re considering using interactive maps in your Angular application definitely Leaflet is a great choice. It’s open, easy to integrate with, and has strong community support.

In my opinion, it’s the best alternative to Google Maps. So, don’t lose the opportunity and check it yourself. I hope it will fit your needs.

Initialize the project

First of all, let’s create a new Angular app using Angular CLI.

ng new angular-leaflet-starter --routing=false --style=scss

Now, let’s generate our main component – MapComponent.

cd angular-leaflet-starter
ng generate component map

Getting started with Leaflet

Using npm package manager install the Leaflet core library as well as ngx-leaflet which is the Leaflet package for the Angular. Additionally, we’ll need TypeScript Leaflet typings.

npm install leaflet
npm install @asymmetrik/ngx-leaflet
npm install --save-dev @types/leaflet

Let’s configure Leaflet in our project.

Go to angular.json and add a reference to Leaflet stylesheets in styles array.

...
"styles": [
              "src/styles.scss",
              "./node_modules/leaflet/dist/leaflet.css"
            ],
...
angular.json

Now it’s time to import LeafletModule into the AppModule (or the other module you’d like to use).

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';

import {AppComponent} from './app.component';
import {LeafletModule} from '@asymmetrik/ngx-leaflet';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    LeafletModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
}
app.module.ts

Let’s go into the component code, starting from the HTML template.

Replace default text:

<p>map works!</p>
map.component.html

With div element where Leaflet map will be placed:

<div id="map"
     leaflet
     [leafletOptions]="mapOptions">
</div>
map.component.html

Let’s add some code to MapComponent stylesheets. We always have to specify the height for our map box.

#map {
  height: 600px;
}
map.component.scss

Okay, let’s go into MapComponent code and introduce MapOptions object the map will use to render.

Let’s take a look at the MapComponent code:

import {Component, OnInit} from '@angular/core';
import {latLng, MapOptions, tileLayer} from 'leaflet';

@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {

  mapOptions: MapOptions;

  constructor() {
  }

  ngOnInit() {
    this.initializeMapOptions();
  }

  private initializeMapOptions() {
    this.mapOptions = {
      center: latLng(51.505, 0),
      zoom: 12,
      layers: [
        tileLayer(
          'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
          {
            maxZoom: 18,
            attribution: 'Map data © OpenStreetMap contributors'
          })
      ],
    };
  }

}
map.component.ts

At this point, you’re able to run the Angular app and see the map. If you simply need the plain map displayed it will be enough for you.

If you want to have access to the Map object for example to add new layers, markers, or anything else, please follow the rest of this article.

Let’s introduce and initialize the map variable and add a simple marker to the map. We need some modifications to our MapComponent code.

<div id="map"
     leaflet
     (leafletMapReady)="onMapReady($event)"
     [leafletOptions]="mapOptions">
</div>
map.component.html

As you can see leafletMapReady event listener has been introduced. It’s time to implement onMapReady method where we pass $event (in this case it’s a Leaflet Map object).

import {Component, OnInit} from '@angular/core';
import {latLng, MapOptions, tileLayer, Map, Marker, icon} from 'leaflet';

@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {

  map: Map;
  mapOptions: MapOptions;

  constructor() {
  }

  ngOnInit() {
    this.initializeMapOptions();
  }

  onMapReady(map: Map) {
    this.map = map;
    this.addSampleMarker();
  }

  private initializeMapOptions() {
    this.mapOptions = {
      center: latLng(51.505, 0),
      zoom: 12,
      layers: [
        tileLayer(
          'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
          {
            maxZoom: 18,
            attribution: 'Map data © OpenStreetMap contributors'
          })
      ],
    };
  }

  private addSampleMarker() {
    const marker = new Marker([51.51, 0])
      .setIcon(
        icon({
          iconSize: [25, 41],
          iconAnchor: [13, 41],
          iconUrl: 'assets/marker-icon.png'
        }));
    marker.addTo(this.map);
  }

}
map.component.ts

Leaflet assets usage

In order to use Leaflet assets such as marker-icon.png we mentioned in the code above it’s required to provide some config modifications.

Go back into the angular.json configuration file and modify it a little bit. Otherwise, it won’t be possible to render the icon.

...
"assets": [
              "src/favicon.ico",
              "src/assets",
              {
                "glob": "**/*",
                "input": "./node_modules/leaflet/dist/images",
                "output": "assets/"
              }
            ]
...
angular.json

At this point, it’s ready to go. Let’s test it.

Final results

Before running the project please replace auto-generated welcome page content in app.component.html with app-map component selector.

<app-map></app-map>
app.component.html

Okay, finally it’s time to run the app.

ng serve

Browse to http://localhost:4200 and you should see the final result.

As you can see the map with an icon is ready to go.

So, that’s it for now. Stay tuned, soon I’ll deliver you more content regarding using Leaflet in the Angular framework.

Good luck with Leaflet integration into your Angular application.

Hope it was useful for you. Let me know if you have any questions.

Resources

6 thoughts on “Use Leaflet in your Angular 10 project for interactive maps”

Leave a Reply

Your email address will not be published.