4

I'm a bit desperate with this. I have a component that takes data and renders a map with the information of this data. All fine here. I put markers on this map and I want to do a click function in the marker. Those function call another function defined in the component and bring me data to show it in a modal. But, when I click the marker, I receive this error:

this.getInfoAlteracion is not a function

I don't know why. I prove a lot of things but I can't see the error. Here's my code:

import { Component, OnInit } from '@angular/core';
import * as L from 'leaflet';
import 'leaflet.markercluster';
import { MapService } from './services';
import * as global from 'app/globals';
import { Alteracion } from './dto/alteracion';

@Component({
  selector: 'map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {
  public alteraciones: Alteracion[] = [];
  public alteracion: Alteracion[] = [];

  constructor(private mapService: MapService) {}

  ngOnInit() {
    this.getAlteraciones();
  }


  getAlteraciones() {
    this.mapService.getListAlteraciones(11, 1).subscribe(
      result => {
        this.alteraciones = result;
        this.renderMap();
      },
      err => console.log(err)
    );
  }

  getInfoAlteracion(id_alteracion: string) {
    this.mapService.getInfoAlteracion(id_alteracion).subscribe(
      result => {
        this.alteracion = result;
        console.log(this.alteracion);
      },
      err => console.log(err)
    );
  }

  renderMap() {
    L.Icon.Default.imagePath = 'assets/img/theme/vendor/leaflet/';
    let map: any;

      map = L.map('map', {
            zoomControl: false,
            format: 'image/jpeg',
            center: L.latLng(40.4166395, -3.7046087),
            zoom: 2,
            minZoom: 0,
            maxZoom: 19,
            layers: [this.mapService.baseMaps.Esri]});

      L.control.zoom({ position: 'topleft' }).addTo(map);
      L.control.layers(this.mapService.baseMaps).addTo(map);

    let cluster = L.markerClusterGroup();

    for (let al of this.alteraciones) {
      let marker = L.marker([al.coory, al.coorx]);

      marker.on('click', function(e) {
        alert('Id alteración: ' + al.id_alteracion); // THIS WORKS
        this.getInfoAlteracion(al.id_alteracion); // THIS DON'T WORK
        console.log(this.alteracion);
      });

      cluster.addLayer(marker);
    }
    map.addLayer(cluster);   

}

Any ideas? Thanks in advance!

0

2 Answers 2

10

You need to use an arrow function for your event handler

  marker.on('click', (e) => {
    alert('Id alteración: ' + al.id_alteracion); // THIS WORKS
    this.getInfoAlteracion(al.id_alteracion); // THIS DON'T WORK
    console.log(this.alteracion);
  });

In Javascript & Typescript this is determined by the caller for a function. Arrow functions capture this from the declaration site. Quite simply this way not what you expected it to be.

Sign up to request clarification or add additional context in comments.

Comments

3

Please try like this

import { Component, OnInit } from '@angular/core';
import * as L from 'leaflet';
import 'leaflet.markercluster';
import { MapService } from './services';
import * as global from 'app/globals';
import { Alteracion } from './dto/alteracion';

@Component({
  selector: 'map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {
  public alteraciones: Alteracion[] = [];
  public alteracion: Alteracion[] = [];

  constructor(private mapService: MapService) {}

  ngOnInit() {
    this.getAlteraciones();
  }


  getAlteraciones() {
    this.mapService.getListAlteraciones(11, 1).subscribe(
      result => {
        this.alteraciones = result;
        this.renderMap();
      },
      err => console.log(err)
    );
  }

  getInfoAlteracion(id_alteracion: string) {
    this.mapService.getInfoAlteracion(id_alteracion).subscribe(
      result => {
        this.alteracion = result;
        console.log(this.alteracion);
      },
      err => console.log(err)
    );
  }

  renderMap() {
      const reference=this; // code added
    L.Icon.Default.imagePath = 'assets/img/theme/vendor/leaflet/';
    let map: any;

      map = L.map('map', {
            zoomControl: false,
            format: 'image/jpeg',
            center: L.latLng(40.4166395, -3.7046087),
            zoom: 2,
            minZoom: 0,
            maxZoom: 19,
            layers: [this.mapService.baseMaps.Esri]});

      L.control.zoom({ position: 'topleft' }).addTo(map);
      L.control.layers(this.mapService.baseMaps).addTo(map);

    let cluster = L.markerClusterGroup();

    for (let al of this.alteraciones) {
      let marker = L.marker([al.coory, al.coorx]);

      marker.on('click', function(e) {
        alert('Id alteración: ' + al.id_alteracion); 
        reference.getInfoAlteracion(al.id_alteracion); // code updated
        console.log(this.alteracion);
      });

      cluster.addLayer(marker);
    }
    map.addLayer(cluster);   

}

1 Comment

Why not just use arrow functions if we are using Typescript anyway ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.