besch
besch

Reputation: 45

Angular 2, child component using with google maps events losing context

I have a case when I am using component in component. By accessing properties of child component via @ViewChild, I am getting undefined for methods in child component.

// Parent component

declare var google: any;
@Component({
  selector: 'app-map',
  templateUrl: `
    <div id="map"></div>
    <app-context-menu></app-context-menu>`,
  styleUrls: ['./map.component.css'],
  providers: [CitiesService],
})

export class MapComponent implements AfterViewInit {
  @ViewChild(ContextMenuComponent) contextMenu: ContextMenuComponent;
  user: UserInterface;
  city: any;
  map: any;

  constructor(
    private userStorage: UserStorage, 
    private citiesService: CitiesService,
    private theMap: TheMap,
  ) {}

  ngAfterViewInit() {
    this.findUserCityCoords();
  }

  inittializeMap(mapOpts) {

    let mapProps = {
      center: new google.maps.LatLng(mapOpts.lat, mapOpts.lng),
      zoom: mapOpts.zoom,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    let map = new google.maps.Map(document.getElementById('map'), mapProps);
    let menu = this.contextMenu;

    map.addListener('rightclick', (e) => {
      console.log('map', this);
      console.log('menu', this.contextMenu);
      this.contextMenu.open(e);
    });
  }

  findUserCityCoords() {
    let userCity = this.userStorage.getFromStorage().city;

    this.citiesService.getCityConfig()
      .subscribe(cities => {
        cities.forEach(city => {
          if (city.name === userCity) this.inittializeMap(city.center);
        });
      });
  }

From this class when 'map event listener' calls 'menu.open(e);' the context changes and inside child component, the methods of child component are not available. To call i.e. 'this.draw()' method.

// Child component
import { Component, OnInit, ElementRef, AfterViewInit } from 

'@angular/core';
import { TheMap } from '../../services/mapServices/TheMap';
import { Marker } from '../../services/mapServices/marker.service';
declare var google: any;

@Component({
  selector: 'app-context-menu',
  templateUrl: './context-menu.component.html',
  styleUrls: ['./context-menu.component.css']
})
export class ContextMenuComponent {
  overlay;
  el;

  constructor(
    private theMap: TheMap, 
    private marker: Marker,
    private elementRef: ElementRef
  ) {
    this.overlay = new google.maps.OverlayView();
  }

  ngAfterViewInit() {}

  open(e) {
    let map = this.theMap.getMap();
    this.overlay.set('position', e.latLng);
    this.overlay.setMap(map);
    this.draw(); // <---- Here, this.draw() is not a function
    // So I can access properties from constructor but not this.draw() and other methods of this class
  };

  draw() {
    // ....
  }

How can I properly implement google's map 'rightclick' event listener (probably with 'bind') to use my child's component methods. Thanks

Upvotes: 1

Views: 863

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657937

Not sure I understand the question but () => (arrow function) might be what you're looking for

map.addListener('rightclick', (e) => {
  console.log('map', this);
  console.log('menu', menu);
  this.contextMenu.open(e);
});

Upvotes: 1

Related Questions