Building Maps in Angular using Leaflet, Part 3: The Popup Service


While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

In my last post, we expanded upon our Angular Leaflet project by creating a service to serve up Markers. We’re going to now do the same thing for popups.

Our map is now populated with markers, and we’re going to set up our map so that the user will be presented with a pop-up containing information about a selected marker.


By now, our directory structure should look like this:

|_ node_modules/
|_ package.json
\_ src/
    \_ app/
        |_ app.module.ts
        |_ app.routing.ts
        |_ app.component.ts
        |_ app.component.html
        |_ app.component.scss
        |_ map/
        |     |_ map.component.ts
        |     |_ map.component.html
        |     \_ map.component.scss
        \_ _services/
              |_ marker.service.ts

Just as we did with the marker service, navigate to the _services/ directory and use the Angular CLI’s generate command to create our pop-up service:

$ ng generate service pop-up

Add this new service as a provider in your app.module.ts.

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

import { AppComponent } from './app.component';
import { MapComponent } from './map/map.component';
import { MarkerService } from './_services/marker.service';
import { PopUpService } from './_services/pop-up.service';

  declarations: [
  imports: [
  providers: [
  bootstrap: [AppComponent]
export class AppModule {}

Designing Our Pop-ups

Crack open your new PopUpService and create an empty function responsible for creating a pop-up:

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

  providedIn: 'root'
export class PopUpService {

  constructor() { }

  makeCapitalPopup(data: any): string {


This function will be responsible for taking our marker data and creating a beautifully formatted pop-up.

We’re only concerned with what goes inside the pop-up, as Leaflet will handle the actual pop-up itself.

Our data are very simple so we’re going to keep this basic:

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

  providedIn: 'root'
export class PopUpService {

  constructor() { }

  makeCapitalPopup(data: any): string {
    return `` +
      `<div>Capital: ${ data.name }</div>` +
      `<div>State: ${ data.state }</div> +
      `<div>Population: ${ data.population }</div>`

Let’s inject this PopUpService within the MarkerService:

constructor(private http: HttpClient,
        private popupService: PopUpService) { }

Huh? A service injected into a service?

Yes! This is a perfectly OK thing to do. By adding our services to our providers stanza within app.modules.ts we are creating the services as singleton providers to the entire application, so Angular won’t complain about dependency.

Back to our recently-injected MarkerService: before we add each circle to the map, we’ll need to bind them to their respective pop-ups.

makeCapitalCircleMarkers(map: L.map): void {
    this.http.get(this.capitals).subscribe((res: any) => {

      // Find the maximum population to scale the radii by.
      const maxVal = Math.max(...res.features.map(x => x.properties.population), 0);

      for (const c of res.features) {
        const lat = c.geometry.coordinates[0];
        const lon = c.geometry.coordinates[1];
        const circle = L.circleMarker([lon, lat], {
          radius: MarkerService.ScaledRadius(c.properties.population, maxVal)
        }); //.addTo(map); <-- removed this



Build and run your application and click one of your markers.

Coming at you with some capital city facts


In the next post, we’ll learn how to plot the state shapes and generate a nice choropleth map.

Happy Mapping!

Creative Commons License