The error appears in the browser, when I click on any pin. No pop-up is displayed, nothing happens, just the error in the console.
Below you will find the component that displays the map and the pins and it should display the pop-up. The service is injected in the constructor.
The same service variable is successfully used when populating the map with pins.
import { Component, OnInit } from '@angular/core';
import * as L from 'leaflet';
import { PowerPlantService } from 'src/app/services/power-plant.service';
import { PowerPlant } from 'src/app/models/power-plant.model';
import { Observable } from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
//coordinates for Brasov
private latitude: number = 45.6427;
private longitude: number = 25.5887;
marker!: CustomPinMarker ;
private map!: L.Map;
private centroid: L.LatLngExpression = [this.latitude, this.longitude];
powerPlantList!: PowerPlant[];
ngOnInit(): void {
this.initMap();
}
constructor(private powerPlantService: PowerPlantService) {
}
private initMap(): void {
this.map = L.map('map', {
center: this.centroid,
zoom: 2.8
});
const tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
minZoom: 2.8,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
});
tiles.addTo(this.map);
/*
the get request made through the HttpClient call will generate an Observable type to which we have to subscribe and unsubscribe at the end.
*/
this.powerPlantService.getAll().subscribe(powerPlantArrayFromGet => {
console.log(powerPlantArrayFromGet);
this.powerPlantList = powerPlantArrayFromGet;
this.powerPlantList.forEach( (element) => {
if (element.published) {
this.marker = new CustomPinMarker([element.latitude!, element.longitude!], element.gppd_idnr).on('click', this.onPinClick).addTo(this.map);
}
});
})
}
onPinClick() : void{
console.log("In pinclick method");
let observableVar! : Observable<PowerPlant>;
let powerPlant! : PowerPlant;
observableVar = this.powerPlantService.findByGPPD_INDR(this.marker.getId());
observableVar.subscribe(data => {powerPlant = data});
this.marker.bindPopup(""+ powerPlant.powerPlant_name + '<br\>' + powerPlant.country_name + '<br\>' + powerPlant.est_generation_gwh_2017
+ '<br\>' + powerPlant.primaryFuel ).openPopup();
}
}
export class CustomPinMarker extends L.Marker {
gppd_idnr: String | undefined;
constructor(latLng: L.LatLngExpression, gppd_idnr: string | String | undefined, options?: L.MarkerOptions) {
super(latLng, options);
this.gppd_idnr = gppd_idnr;
}
getId() : any{
return this.gppd_idnr;
}
}
This is the correct answer after some modifications:
import { Component, OnInit } from '@angular/core';
import * as L from 'leaflet';
import { PowerPlantService } from 'src/app/services/power-plant.service';
import { PowerPlant } from 'src/app/models/power-plant.model';
import { Observable } from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
//coordinates for Brasov
private latitude: number = 45.6427;
private longitude: number = 25.5887;
private map!: L.Map;
private centroid: L.LatLngExpression = [this.latitude, this.longitude];
powerPlantList!: PowerPlant[];
ngOnInit(): void {
this.initMap();
}
constructor(private powerPlantService: PowerPlantService) { }
private initMap(): void {
this.map = L.map('map', {
center: this.centroid,
zoom: 2.8
});
const tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
minZoom: 2.8,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
});
tiles.addTo(this.map);
// this queries the database and retrieves a list of all the elements
this.powerPlantService.getAll().subscribe(powerPlantArrayFromGet => {
console.log(powerPlantArrayFromGet);
this.powerPlantList = powerPlantArrayFromGet;
// this loops through the list and creates and places a pin on the map at the location of each element
this.powerPlantList.forEach( (element) => {
if (element.published) {
const that = this;
//console.log(element.gppd_idnr + " 1") ;
// this create the pin to be placed on the map and attaches to it a pop-up that, when clicked, will retrieve from the database information about that item and display it on the pop-up
let marker = new L.Marker([element.latitude!, element.longitude!])
.on('click', function() {
let observableVar! : Observable<PowerPlant>;
let powerPlant! : PowerPlant;
//console.log(element.gppd_idnr + " 2");
observableVar = that.powerPlantService.findByGPPD_INDR(element.gppd_idnr + "");
// the is where the interogation is done (above) and the pop-up is populated with the relevant information
observableVar.subscribe(
data =>
{
powerPlant = data
var latlong : L.LatLng = new L.LatLng(<number> powerPlant.latitude, <number> powerPlant.longitude);
marker.setLatLng(latlong).bindPopup(
powerPlant.powerPlant_name +
'<br\>' +
powerPlant.country_name +
'<br\>' +
powerPlant.est_generation_gwh_2017 +
'<br\>' +
powerPlant.primaryFuel )
.openPopup();
})
})
.addTo(that.map);
}
});
})
}
}