How to set map to center on a marker? - Angular Google Maps

Compiler v2 picture Compiler v2 · Jul 4, 2019 · Viewed 10.1k times · Source

I cannot center my Google map on a marker after I geocode.

I have two markers: The initial marker (the one that is centered on, does not change), the other one changes based on the geocoding, and after geocoding, it will be centered on every time.

My code: TS

zoom = 10;

addressData: FormGroup;
submitted = false;
success = false;

lat: number;
lng: number;

userLat: number;
userLng: number;

currentCenter = { lat: null, lng: null };

private geoCoder: google.maps.Geocoder;

@ViewChild('googleMap') googleMap: AgmMap;

constructor(private maps: MapsAPILoader, private bulider: FormBuilder) { }

ngOnInit() {
    this.addressData = this.bulider.group({
        address: ["", Validators.required],
    });

    this.maps.load().then(() => {
        this.geoCoder = new google.maps.Geocoder();
    });
}

getAddress() {

    this.submitted = true;

    if (this.addressData.invalid) {
        return;
    }

    this.success = true;

    this.googleMap.mapReady.subscribe(map => {

        // Need to use two parameters in order to use Geocoder
        this.geoCoder.geocode(this.addressData.controls['address'].value, (results, status) => {
        if (status === google.maps.GeocoderStatus.OK) {
            this.userLat = results[0].geometry.location.lat();
            this.userLng = results[0].geometry.location.lng();
        } else {
            alert('Geocode was not successful for the following reason: ' + status);
        }

    }).then(place => {
        this.currentCenter = { lat: place.geometry.location.lat(), lng: place.geometry.location.lng() };
    }).catch(err => {
        console.log("Error: " + err);
    });

    this.submitted = false;
}

HTML

<!-- Google maps, the starting latitude & longitude -->
<agm-map [latitude]="currentCenter.lat" [longitude]="currentCenter.lng" [zoom]="zoom" [mapTypeControl]='true'
#googleMap>
    <!-- Static marker -->
    <agm-marker [latitude]="defaultCenter.lat" [longitude]="defaultCenter.lng"></agm-marker>

    <!-- User geolocation marker, changes -->
    <agm-marker [latitude]="currentCenter.userLat" [longitude]="currentCenter.userLng"></agm-marker>
</agm-map>

Expected:

After Geocoding, the map should center on the marker from the given address every time.

Actual:

The Geocoder finds the address but does not center the map on the placed marker based on the address.

Update

I cannot use Vadim's code because the compiler tells me that I need two arguments for the Geocode, but Vadim's code only has one. I cannot use this code. Also, if I add the second argument, it will then say that then does not exist.

this.googleMap.mapReady.subscribe(map => {
    // This line needs two parameters not one      

    this.geoCoder.geocode(this.addressData.controls['address'].value)
    .then(place => {
        this.currentCenter = { lat: place.geometry.location.lat(), lng: place.geometry.location.lng() };
    }).catch(err => {
        console.log("Error: " + err);
    });
});

Answer

Vadim Gremyachev picture Vadim Gremyachev · Jul 10, 2019

There is no need to resort to Google Maps API or invoke Map component triggerResize method, to update map center the following approach could be considered:

a) set map center to default value once the map is loaded

<agm-map
  [latitude]="currentCenter.lat"
  [longitude]="currentCenter.lng"
  [zoom]="zoom"
  [mapTypeControl]="true"
>
  <!-- Static marker -->
  <agm-marker
    [latitude]="defaultCenter.lat"
    [longitude]="defaultCenter.lng"
  ></agm-marker>

  <!-- User geolocation marker, changes -->
  <agm-marker
    [latitude]="currentCenter.lat"
    [longitude]="currentCenter.lng"
  ></agm-marker>
</agm-map>

For that matter two properties are introduced:

  • currentCenter - current map center
  • defaultCenter - default (original) map center

b) once the address is resolved, update map center like this:

ngOnInit() {
    this.agmMap.mapReady.subscribe(map => {
      this.geocode("New York, USA").then(place => {
        this.currentCenter = { lat: place.geometry.location.lat(), lng: place.geometry.location.lng()};
      })
      .catch(err => {
        console.log(err);
      });
    });
 }

Example

declare var google: any;

import { Component, ViewChild, OnInit} from "@angular/core";
import { AgmMap } from "@agm/core";

@Component({
  selector: "app-map",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  constructor() {}

  defaultCenter = {lat: 55.5815245, lng: 36.8251383};
  currentCenter = Object.assign({}, this.defaultCenter);
  zoom = 3;

  @ViewChild(AgmMap) agmMap;

  ngOnInit() {
    this.agmMap.mapReady.subscribe(map => {
      this.geocode("New York, USA").then(place => {
        this.currentCenter = { lat: place.geometry.location.lat(), lng: place.geometry.location.lng()};
      })
      .catch(err => {
        console.log(err);
      });
    });
  }

  geocode(address: string): Promise<any> {
    const geocoder = new google.maps.Geocoder();
    return new Promise((resolve, reject) => {
      geocoder.geocode(
        {
          address: address
        },
        (results, status) => {
          if (status === google.maps.GeocoderStatus.OK) {
            resolve(results[0]);
          } else {
            reject(new Error(status));
          }
        }
      );
    });
  }
}

Update

Getting address from input element:

<input [(ngModel)]="addressText">
<button (click)="findPlace()">Find a place</button>


findPlace() {
    this.geocode(this.addressText).then(place => {
      this.currentCenter = { lat: place.geometry.location.lat(), lng: place.geometry.location.lng()};
    })
    .catch(err => {
      console.log(err);
    });
}