setCenter not working in angular2-google-maps

17.6k views Asked by At
import { GoogleMapsAPIWrapper } from '@agm/core';
import { Component, Input } from '@angular/core';

@Component({
  selector: 'core-map',
  styleUrls: [ './map.component.scss' ],
  templateUrl: './map.component.html',
})
export class MapComponent {
  constructor(
    public gMaps: GoogleMapsAPIWrapper
  ) {}

  public markerClicked = (markerObj) => {
    this.gMaps.setCenter({ lat: markerObj.latitude, lng: markerObj.longitude });
    console.log('clicked', markerObj, { lat: markerObj.latitude, lng: markerObj.longitude });
  }
}
console output: Object {lat: 42.31277, lng: -91.24892}

Also have tried panTo with the same result.

3

There are 3 answers

2
Brian Burton On BEST ANSWER

Perhaps it's been added since Christopher posted his solution, but agm-map has a mapReady event that returns the raw map object that you can use to access setCenter().

Modification of your original code:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'core-map',
  styleUrls: [ './map.component.scss' ],
  templateUrl: './map.component.html',
})
export class MapComponent {
  protected map: any;

  constructor() {}

  protected mapReady(map) {
    this.map = map;
  }

  public markerClicked = (markerObj) => {
    if (this.map)
      this.map.setCenter({ lat: markerObj.latitude, lng: markerObj.longitude });
    console.log('clicked', markerObj, { lat: markerObj.latitude, lng: markerObj.longitude });
  }
}

Then add the following to agm-map

<agm-map (mapReady)="mapReady($event)"></agm-map>
0
Pavel Popov On

google.maps.Map is accessible on MapReady event

<agm-map #geoMap [ngClass]="{'hide': !(showGeoMapDiagram$ | async)}"
    (window:resize)="onWindowResize()"    
    [latitude]="centerMapLat"
    [longitude]="centerMapLng"
    [mapTypeId]="mapTypeId"
    [mapTypeControl]="true"
    [zoom]="mapZoom"
    (mapReady)="onMapReady($event)"

>
</agm-map>

In code "event" contains an instance of google.maps.Map:

onMapReady(event: any)
  {
    this.diagramOverlay = new ShotDiagramOverlay();
    this.diagramOverlay.setMap(event);
    this.drawDiagramOnGeoMapSubscription = this.diagramOverlay.readyToDrawAction$.subscribe(() => this.drawDiagramOnGeoMap())
  }
6
Christopher Marshall On

Finally got this working. Had to create a child component of agm-map and create an output that on load, grabs the native google maps api wrapper and passes into my parent map component. I wish they made it so you could just grab the gmaps api wrapper in the regular agm-map component. Works with panTo as well.

PARENT COMPONENT MARKUP

<agm-map [latitude]='lat' [longitude]='lng'
  [usePanning]='true'>
  <agm-marker *ngFor='let location of locations'
    [latitude]='location.latitude'
    [longitude]='location.longitude'
    [iconUrl]='location.icon'
    (markerClick)='markerClicked(location)'></agm-marker>
  <core-map-content (onMapLoad)='loadAPIWrapper($event)'></core-map-content>
</agm-map>

PARENT COMPONENT

/**
 * Map Component
 * API Docs: https://angular-maps.com/docs/api/latest/ts/
 */
import { GoogleMapsAPIWrapper } from '@agm/core';
import { Component, Input } from '@angular/core';

declare var google:any;

@Component({
  selector: 'core-map',
  styleUrls: [ './map.component.scss' ],
  templateUrl: './map.component.html',
})
export class MapComponent {
  @Input() lat: number;
  @Input() lng: number;
  @Input() locations: {};
  map: any;

  constructor(
    public gMaps: GoogleMapsAPIWrapper,
  ) {}

  public loadAPIWrapper(map) {
    this.map = map;
  }

  public markerClicked = (markerObj) => {
    const position = new google.maps.LatLng(markerObj.latitude, markerObj.longitude);
    this.map.panTo(position);
  }
}

CHILD COMPONENT

import { Component, EventEmitter, OnInit, Output } from '@angular/core';

import { GoogleMapsAPIWrapper } from '@agm/core';

@Component({
  selector: 'core-map-content',
  template: '',
})
export class MapContentComponent implements OnInit {
  @Output() onMapLoad: EventEmitter<{}> = new EventEmitter<{}>();

  constructor(public gMaps: GoogleMapsAPIWrapper) {}

  ngOnInit() {
    this.gMaps.getNativeMap().then((map) => {
      this.onMapLoad.emit(map);
    });
  }
}