62

I am working with angular2-google-maps and latest version of Angular2. I am trying to convert some of the local map component functions into services in their own file maps.service.ts. For example:

map.component.ts

getGeoLocation(lat: number, lng: number) {
if (navigator.geolocation) {
    let geocoder = new google.maps.Geocoder();
    let latlng = new google.maps.LatLng(lat, lng);
    let request = { latLng: latlng };
    geocoder.geocode(request, (results, status) => {
      if (status == google.maps.GeocoderStatus.OK) {
        let result = results[0];
        if (result != null) {
          this.fillInputs(result.formatted_address);
        } else {
          alert("No address available!");
        }
      }
    });
}
}

Into something like: maps.service.ts

getGeoLocation(lat: number, lng: number): Observable<google.maps.GeocoderResult[]> {
    let geocoder = new google.maps.Geocoder();
    let latlng = new google.maps.LatLng(lat, lng);
    let request = { latLng: latlng };
    return new Observable((observer: Observer<google.maps.GeocoderResult[]>) => {
        geocoder.geocode({ request }, (
            (results: google.maps.GeocoderResult[], status: google.maps.GeocoderStatus) => {
                if (status == google.maps.GeocoderStatus.OK) {
                    observer.next(results);
                    observer.complete();
                } else {
                    console.log('Geocoding service failed due to: ' +status);
                    observer.error(status);
                }
            }
        ));
    });
}

The issue I'm getting is that google variable is not being recognized when I try to use Observer<google.maps.GeocoderResult[]>. I have declare var google: any; outside of the service class as well.

The google variable works in my map.componenet.ts but doesn't get recognized in the maps.service.ts.

Milo
  • 3,365
  • 9
  • 30
  • 44

14 Answers14

109

Angular 6 & 7 steps (should also work for every other Angular version):

  1. npm install @types/googlemaps --save-dev
  2. Add googlemaps to the types array in both filestsconfig.app.json respectively in tsconfig.spec.json (save both files)
  3. At the top of your controller.ts
/// <reference types="@types/googlemaps" />
  1. Restart npm server

The types array should look like these in both files

{ 
    "compilerOptions": { 
        "types": ["googlemaps","othertype",...]
    }
}

You can delete both declaration types from the components: import {} from '@types/googlemaps'; declare var google: any; You don't have to include any of them.

PS: If you are using agm-s GoogleMapsAPIWrapper.getNativeMap() you must convert the map object before you use it. For example turning on the traffic layer:

this.apiWrapper.getNativeMap().then(map => {
    this.trafficLayer = new google.maps.TrafficLayer();
    const gMap: any = map;
    this.trafficLayer.setMap(gMap as google.maps.Map);
});
Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
Zsolt Tolvaly
  • 3,528
  • 4
  • 26
  • 25
61

I was facing the same problem I tried :

declare var google: any;

But it didn't work for me .
I found this answer and it worked for me .
First make sure you installed the typings for google maps
npm install @types/googlemaps --save --dev

--dev flag is deprecated. Use npm install @types/googlemaps --save-dev

And Then in your Controller

import {} from '@types/googlemaps';
Community
  • 1
  • 1
Ayman Sharaf
  • 889
  • 2
  • 10
  • 18
  • 1
    This worked for me...just want to add that in Angular 2, I added `import {} from '@types/googlemaps';` to the same file after `import { NguiMapModule} from '@ngui/map';` in my shared.module.ts. – newman Jul 23 '17 at 14:42
  • 1
    It seems like Typescript linting doesn't like `import {} from '@types/googlemaps';` anymore, but suggests: `import { } from 'googlemaps'` – AJ Zane Apr 24 '18 at 00:13
  • 1
    can somebody explain (or even better to drive me to ts doc page) about this "empty" import. Nevertheless it works it looks like unused import. Wondered why does this help... – DicBrus May 31 '18 at 11:30
20

To prevent more suffering of anyone else with this issue.

npm install @google/maps

https://www.npmjs.com/package/@google/maps

THEN:

import { google } from '@google/maps';

Basically we're importing the google object from the package @google/maps.

Tested in 2018 after @types/googlemaps stopped working.

Milo
  • 3,365
  • 9
  • 30
  • 44
clse
  • 648
  • 1
  • 7
  • 10
13

Add

declare var google: any;

after the TypeScript imports

See also https://github.com/SebastianM/angular2-google-maps/issues/689

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
11
ERROR: [ts] Cannot import type declaration files. Consider importing ‘googlemaps’ instead of ‘@types/googlemaps’

solution: change import {} from ‘@types/googlemaps’; for

/// <reference types=”@types/googlemaps” />

ERROR: while compiling, error TS2304: Cannot find name ‘google’.

solution: add declare var google: any; below @types/googlemaps reference


ERROR: while compiling error TS2503: Cannot find namespace ‘google’.

solution: Add to tsconfig.app.json : "types": ["googlemaps"] and restart


ERROR: map doesn’t load correctly and in the web browser console you read “Google Maps Javascript API Warning: NoApiKeys”

solution: add a valid api key inside the javascript file in index.html, should look like this <script type=”text/javascript” src=”http://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_HERE"></script> you can get an API key from here https://developers.google.com/maps/documentation/javascript/get-api-key


ERROR:Cannot find name 'google'

Well, this is in case you just installed the types with:

npm i -D @types/google.maps

and you tried to used them. Sometimes in tsconfig.app.json there is empty type array, which prevents the automatic import. Remove "types": [] and could work. It worked for me once.

makkasi
  • 6,328
  • 4
  • 45
  • 60
  • good answer for showing all the possibilities including the one that fixed it for me - tsconfig.app.json, which also avoided installing @google/maps – wlf May 24 '20 at 22:54
  • 1
    Don't forget to restart your dev environment. I've found that is necessary to get the reference seen. – tim.rohrer Sep 27 '20 at 13:54
4

In my case I was getting 2 types of errors:

  • Cannot find namespace google
  • Cannot find name google

Since in my code I am using:

let autocomplete = new google.maps.places.Autocomplete(...)

let place: google.maps.places.PlaceResult = autocomplete.getPlace();

So fixed it by adding this:

declare var google: any;

declare namespace google.maps.places {
    export interface PlaceResult { geometry }
}
Milo
  • 3,365
  • 9
  • 30
  • 44
odiaz
  • 241
  • 2
  • 3
  • I just had types = ["google.maps"] in my tsconfig.app.json and all was working fine until I tried to add prerendering via Universal: the SSR server would not build with the error `Cannot find namespace 'google'.`. This fix worked for me, I just had to modify the namespace declaration to include the functions I'm using, ie; ```declare namespace google.maps.places {export interface Autocomplete { getPlace }}``` in one file and ```declare namespace google.maps.places { export interface ComponentRestrictions { country }}``` in another. – momargoh Apr 15 '22 at 18:07
4

Install reference

npm i -D @types/google.maps

Add this line at the beginning (meaning line 1, with nothing before) of your Typescript file :

/// <reference types="@types/google.maps" />

Triple Slash Documentation

Source

Garvit Jain
  • 1,862
  • 2
  • 19
  • 27
3

It is working for me also:

First install the typings for google maps in cmd on root of project

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

And then add in your .ts component file below:

import {} from '@types/googlemaps';
Milo
  • 3,365
  • 9
  • 30
  • 44
Gauravbhai Daxini
  • 2,032
  • 2
  • 22
  • 28
3

I have a similar problem with Angular 6, and I did all the possible solutions mentioned above but no luck. Finally, I manage to solve this problem by adding googlemaps into types inside tsconfig.app and tsconfig.spec files. Hope it helps for others.

chaendler
  • 61
  • 2
2

What worked for me was

npm install --save-dev @types/googlemaps

and then at the very top of your .ts page add this

/// <reference types="@types/googlemaps" />

enter image description here

Ruan
  • 3,969
  • 10
  • 60
  • 87
1

Straight solution, Add "googlemaps" to types array in tsconfig.app.json. And I didnt need to declare anything like, declare var google: any;. Just adding googlemaps in tsconfig works.

"types": ["googlemaps"]
Mohsin Younas
  • 324
  • 4
  • 12
0

If anyone is struggling with this because Webstorm undescores the code even after installing types and adding them to tsconfig... restart the Webstorm. It took me an hour.

Tukkan
  • 1,574
  • 2
  • 18
  • 33
0

Noting solved the problem for me. After following the top rated answer still didn't worked only worked after adding this

npm i @types/googlemaps@3.39.13 --save-dev

make sure you run this before ng serve and make sure to restart the server if its running.

dt170
  • 417
  • 2
  • 12
-1
`
import { Observable } from 'rxjs';
import { GoogleMapsAPIWrapper, MapsAPILoader } from '@agm/core';
import { Injectable, NgZone } from '@angular/core';
declare var google: any;

@Injectable({
  providedIn: 'root'
})
export class MapService extends GoogleMapsAPIWrapper {
  geocoder: Promise<any>;
  constructor(private __loader: MapsAPILoader, private __zone: NgZone) {
    super(__loader, __zone);
    this.geocoder = this.__loader.load().then(() => new google.maps.Geocoder());
  }

  getLatLan(address: string): Observable<any> {
    return Observable.create(observer => {
      this.geocoder.then((geocoder) => {
        geocoder.geocode({ 'address': address }, (results, status) => {
          if (status === google.maps.GeocoderStatus.OK) {
            observer.next(results[0].geometry.location);
            observer.complete();
          } else {
            console.error('Error - ', results, ' & Status - ', status);
            observer.next({});
            observer.complete();
          }
        });
      });
    });
  }
}`

This is a service with a method to get the address and return lan and lat.

Ramin Ar
  • 1,213
  • 13
  • 10