Angular Google Maps with Places Search, Draggable Marker using Angular Google Maps (@agm/core)

In this Angular tutorial, we’ll learn how to use Google Maps with Draggable Marker and Place search bar to get Address and Latitude, Longitude coordinates in Angular 10/9/8/7/6/5/4 project using @agm package. Google maps are used in many applications as a location with visible maps plays an important role to make information more user-friendly. Embedded…

By.

•

min read

In this Angular tutorial, we’ll learn how to use Google Maps with Draggable Marker and Place search bar to get Address and Latitude, Longitude coordinates in Angular 10/9/8/7/6/5/4 project using @agm package.

Google maps are used in many applications as a location with visible maps plays an important role to make information more user-friendly. Embedded Maps can display markers of location or enable visual selection of address or show geographical location reviews etc.

We will add Google Maps in an Angular project using the Angular Google Maps module. Adding/ Embedding Google Maps in an Angular project becomes very easy by using this module. Here we will explain step by step tutorial to make it even easier with a new sample Angular project.

The Google Maps added into our application will have the following features:

  1. Draggable Marker to get coordinates on Map.
  2. How to get Google Maps API from the developer console.
  3. Use Geocoder to fetch the address of the marker placed.
  4. The places or address search bar on Google map, to search nearby places.
  5. Display the address of dragged area marker.

[lwptoc]

Let’s get mapped …

 

How to Add Google Maps with Draggable Marker and Places Search in Angular?

To add google maps to the angular app, you will be following these quick steps:

  • Step 1 – Create Angular Application
  • Step 2 – Install @agm/core Google Map Library
  • Step 3 – Install Google Map Types
  • Step 4 – Configure App Module
  • Step 5 – Get Google API Key
  • Step 6 – Adding Google Maps in Component
  • Step 7 – Add Places/ Address Search Bar
  • Step 8 – Run Application

 

Check working demo here

 

Step 1 – Create Angular Application

To create a new Angular project, we’re using Ng CLI commands. Make sure you have installed by executing below command

$ npm install -g @angular/cli

Create a new Angular project

$ ng new angular-google-maps-app
? Would you like to add Angular routing? No
? Which stylesheet format would you like to use? SCSS

Move inside the project directory

$ cd angular-google-maps-app

Run project

$ ng serve --open

 

Step 2 – Install @agm/core Google Map Library

To use Google Maps in Angular application, install the @agm/core package.

Run the following command to install AGM in Angular

$ npm install @agm/core --save

 

Step 3 – Install Google Map Types

Next, we will install GoogleMaps types library

$ npm install @types/googlemaps --save-dev

Next, open file tsconfig.app.json already available at the root, now add "googlemaps" in types array as shown below

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "types": [
      "googlemaps"
    ]
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ]
}

 

Step 4 – Configure App Module

Next, open the app.module.ts file, import AgmCoreModule then update the imports array

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

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

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AgmCoreModule.forRoot({
      apiKey: 'YOUR-API-KEY-HERE',
      libraries: ['places']
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

During the import of AgmCoreModule we need to define our Google Console API Key under apiKey property. Also, we have enabled the ‘places’ library required to make Places search using the search bar.

Check the next section to get your API key and enable Maps and places services.

 

Step 5 – Get Google API Key

# Step 1: Go to the Google Console portal. You need to signup/ signing with your Google credentials.

# Step 2: Select the project or create a new one. You may need to fill payment details as per the new rules. But they provide free credits so you can easily choose for development purposes.

# Step 3: After creating and selecting the project, click on “Create Credentials”>”API Keys”. Then click on the “Restrict Key” button.

# Step 4: Enable  “Maps Javascript API” and “Places API”

 

Make sure you have enabled three types of API’s services on your key.

Maps JavaScript API (Show Map), Places API (Places search results) & Geocoding API (Convert Lat & Long to address)

Check more details here on How to get Google API key?

 

Step 6 – Adding Google Maps in Component

For creating a Google Map in the template, we add the <agm-map/> component with binding properties for setting latitude, longitude, zoom, and other configurations.

The map will also have a Marker, which is created by adding the <agm-marker/> component.

# Update App Template

Add the AGM template in the App component to show basic Google Map with the current location. To get current coordinates like longitude & latitude, we will use geolocation service in the navigator.

<!-- app.component.html -->
<agm-map 
[latitude]="latitude" 
[longitude]="longitude" 
[zoom]="zoom" >
  <agm-marker 
  [latitude]="latitude" 
  [longitude]="longitude"></agm-marker>
</agm-map>

 

# Update Component Class

On component load, we’ll call the navigator.geolocation API service to get current position of the user. The setCurrentLocation() method will fetch latitude and longitude to set Google Map to the current location.

//app.component.ts

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent  implements OnInit {
  title: string = 'AGM project';
  latitude: number;
  longitude: number;
  zoom:number;


  ngOnInit() {
    this.setCurrentLocation();
  }

    // Get Current Location Coordinates
    private setCurrentLocation() {
      if ('geolocation' in navigator) {
        navigator.geolocation.getCurrentPosition((position) => {
          this.latitude = position.coords.latitude;
          this.longitude = position.coords.longitude;
          this.zoom = 15;
        });
      }
    }

}

Add Map height in app.component.scss

agm-map {
    height: 300px;
}

Note: Map height is required. Without it, the map will not be visible with 0 height.

That’s it now you have a basic Google Map working in Angular application. Next, we will add a search bar to search for locations from Google API. Then a Draggable Marker to get current location address.

 

 

Step 7 – Add Places/ Address Search Bar

In app.component.html we will now add a search bar with address and Latitude & Longitude information.

The marker is now draggable so that the user can drag it to the desired location.

<strong>[markerDraggable]</strong>option is set to true.

<strong>(dragEnd)</strong>the event will fire to get the address of the current drop.

# Update the App component template

<!-- app.component.html -->
<div class="container">

  <h1>Angular Google Maps with Places Search Example</h1>

  <div class="form-group">
    <label>Enter address</label>
    <input type="text" class="form-control" (keydown.enter)="$event.preventDefault()" placeholder="Search Nearest Location" autocorrect="off" autocapitalize="off" spellcheck="off" type="text" #search>
  </div>

  <agm-map [latitude]="latitude" [longitude]="longitude" [zoom]="zoom">
    <agm-marker [latitude]="latitude" [longitude]="longitude" [markerDraggable]="true"
      (dragEnd)="markerDragEnd($event)"></agm-marker>
  </agm-map>

  <h5>Address: {{address}}</h5>
  <div>Latitude: {{latitude}}</div>
  <div>Longitude: {{longitude}}</div>
</div>

 

# Update Component Class

In app.component.ts we will add Google map Autocomplete method to return address data set.

Geocoder location service will return address based on provided Latitude & Longitude in the method getAddress()

The template reference variable #search on Input field is used to find the key events for fetching addresses based on current location.

The markerDragEnd() method is called after the user stops marker drag to fetch the address of the current marker position.

//app.component.ts

import { Component, OnInit, ViewChild, ElementRef, NgZone } from '@angular/core';
import { MapsAPILoader, MouseEvent } from '@agm/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title: string = 'AGM project';
  latitude: number;
  longitude: number;
  zoom: number;
  address: string;
  private geoCoder;

  @ViewChild('search')
  public searchElementRef: ElementRef;


  constructor(
    private mapsAPILoader: MapsAPILoader,
    private ngZone: NgZone
  ) { }


  ngOnInit() {
    //load Places Autocomplete
    this.mapsAPILoader.load().then(() => {
      this.setCurrentLocation();
      this.geoCoder = new google.maps.Geocoder;

      let autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement);
      autocomplete.addListener("place_changed", () => {
        this.ngZone.run(() => {
          //get the place result
          let place: google.maps.places.PlaceResult = autocomplete.getPlace();

          //verify result
          if (place.geometry === undefined || place.geometry === null) {
            return;
          }

          //set latitude, longitude and zoom
          this.latitude = place.geometry.location.lat();
          this.longitude = place.geometry.location.lng();
          this.zoom = 12;
        });
      });
    });
  }

  // Get Current Location Coordinates
  private setCurrentLocation() {
    if ('geolocation' in navigator) {
      navigator.geolocation.getCurrentPosition((position) => {
        this.latitude = position.coords.latitude;
        this.longitude = position.coords.longitude;
        this.zoom = 8;
        this.getAddress(this.latitude, this.longitude);
      });
    }
  }


  markerDragEnd($event: MouseEvent) {
    console.log($event);
    this.latitude = $event.coords.lat;
    this.longitude = $event.coords.lng;
    this.getAddress(this.latitude, this.longitude);
  }

  getAddress(latitude, longitude) {
    this.geoCoder.geocode({ 'location': { lat: latitude, lng: longitude } }, (results, status) => {
      console.log(results);
      console.log(status);
      if (status === 'OK') {
        if (results[0]) {
          this.zoom = 12;
          this.address = results[0].formatted_address;
        } else {
          window.alert('No results found');
        }
      } else {
        window.alert('Geocoder failed due to: ' + status);
      }

    });
  }

}

 

For making it look beautiful we have added bootstrap.css in index.html

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">

Step 8 – Run Application

That’s it! Run the application $ ng serve --open to see a Google Map with Search Bar to search for places. The marker can be dragged anywhere to get the location address with coordinates.

Check working demo here

Also, check

Angular 13 Google Maps Integration with Markers, Info Windows Tutorial

Conclusion

We have completed a tutorial on adding Google maps in the Angular application with draggable marker and places search. We also discussed how to get a Google API key from the developer console. You make the application work as discussed, make sure to select the correct API from the developer console account.

47 responses to “Angular Google Maps with Places Search, Draggable Marker using Angular Google Maps (@agm/core)”

  1. vinoth kumar Avatar

    how to calculate distance between two latitude and longitude points in angular 6

    1. Jolly.exe Avatar
      Jolly.exe

      •

      Hi Vinoth, you need to use Haversine Formula which takes two sets of Lattitude and Longitude coordinates to give the distance on a flat surface. Try this

  2. william Avatar
    william

    •

    tengo un herror aqui :
    @ViewChild(‘search’)
    public searchElementRef: ElementRef;

    y me dice esto al ejecutar ng serve –open

    ERROR in src/app/home/map/map.component.ts(18,4): error TS2554: Expected 2 arguments, but got 1.

    1. Jolly.exe Avatar
      Jolly.exe

      •

      Try using @ViewChild(‘search’, {static: false})

    2. zé zé zé Avatar
      zé zé zé

      •

      um não, muitos…

  3. carlos Avatar
    carlos

    •

    please sir to the uber animation example give animate MARKER ON GOOGLE MAP WITH CURRENT LOCATION in Angular google Maps

  4. Hiimanshu Arora Avatar
    Hiimanshu Arora

    •

    Hey…I am getting error Uncaught (in promise): TypeError: Cannot read property ‘nativeElement’ of undefined. Help

  5. James Avatar
    James

    •

    How to make the search bar give suggestion on places rather than addresses?

  6. mohamed Avatar
    mohamed

    •

    the search bar dont work and get err in ts can not find name google

    1. Jolly.exe Avatar
      Jolly.exe

      •

      Hi Mohamed, there is some change in code, I have updated code in file app.module.ts.
      Please check the updated post.
      Thanks for pointing out 🙂

      1. Katlego Thabe Avatar
        Katlego Thabe

        •

        Hi Jolly,

        What a beautiful tutorial, however I’m getting the same error “TypeError: Cannot read property ‘maps’ of undefined”. Please tell where I can find the updated code in the file app.module.ts.

    2. Jhorkman Avatar
      Jhorkman

      •

      @Jolly.exe, you forgotten to install “@types/googlemaps”: “^3.30.4”, in dev-dependencies instead add types in tsconfig file

  7. Farhan Avatar
    Farhan

    •

    my search bar is not functioning, help

    1. Jolly.exe Avatar
      Jolly.exe

      •

      Hi Farhan, if you are getting an error in response from Google API, then make sure your API KEY is allowed three types of authentications for Places API, Geocoder API, and Google JS Maps API in Google Developer console as mentioned in the article above.

    2. Ahmad Deedat Avatar
      Ahmad Deedat

      •

      i solved it by add ( language: ‘en’,
      libraries: [‘geometry’, ‘places’]) at app.module:

      @NgModule({
      declarations: […],
      imports: […,
      AgmCoreModule.forRoot({
      clientId: ”,
      //apiVersion: ‘xxx’, // optional
      //channel: ‘yyy’, // optional
      //apiKey: ‘zzz’, // optional
      language: ‘en’,
      libraries: [‘geometry’, ‘places’]
      })
      ],
      providers: […],
      bootstrap: […]
      })

      1. kuldeep Avatar

        i couldn’t resolve , which
        you did involve

    3. bboy Avatar
      bboy

      •

      I also did not work in search.

Leave a Reply

Your email address will not be published. Required fields are marked *