6

As it shows error during build.

ERROR in app/pages/TestPage4/TestPage4.ts:27:27 - error TS2304: Cannot find name 'google'.

27 this.geoCoder = new google.maps.Geocoder; ~~~~~~ app/pages/TestPage4/TestPage4.ts:29:32 - error TS2304: Cannot find name 'google'.

29 const autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement); ~~~~~~ app/pages/TestPage4/TestPage4.ts:33:24 - error TS2503: Cannot find namespace 'google'.

33 const place: google.maps.places.PlaceResult = autocomplete.getPlace(); ~~~~~~

Here is my code below.

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

@Component({
  selector: 'app',
  templateUrl: './TestPage4.html',
  styleUrls: ['./TestPage4.css']
})

export class TestPage4 implements OnInit {
  lat: number;
  lng: number;
  zoom = 1;
  private geoCoder;

  @ViewChild('search', { static: false})
  public searchElementRef: ElementRef;

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

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

      const autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement);
      autocomplete.addListener("place_changed", () => {
        this.ngZone.run(() => {
          //get the place result
          const place: google.maps.places.PlaceResult = autocomplete.getPlace();
          console.log(place);
          //verify result
          if (place.geometry === undefined || place.geometry === null) {
            return;
          }

          for (var i = 0; i < place.address_components.length; i++) {
            let addressType = place.address_components[i].types[0];
            //if (componentForm[addressType]) {
            //  var val = place.address_components[i][componentForm[addressType]];
            //  document.getElementById(addressType).value = val;
            //}
            // for the country, get the country code (the "short name") also
            console.log(addressType);
            if (addressType == "country") {
              console.log(place.address_components[i].short_name);
              console.log(place.address_components[i].long_name);
            }
            else{
              console.log('---others---');
              console.log(place.address_components[i].short_name);
              console.log(place.address_components[i].long_name);
            }
          }

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

As i F12 it new google.maps.Geocoder and shows me it exists here below.
enter image description here But in reality when built it shows the above error.

Update 1:

{
  "compileOnSave": false,
  "compilerOptions": {
    "downlevelIteration": true,
    "importHelpers": true,
    "module": "esnext",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ],
    "baseUrl": "src",
    "paths": { "@angular/*": ["node_modules/@angular/*"] }
  }
}

This is the tsconfig.json file.

Update 2:
Using declare var google: any; works on
this.geoCoder = new google.maps.Geocoder; and
const autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement); but fails on google.maps.places.PlaceResult Cannot find namespace 'google' const place: google.maps.places.PlaceResult = autocomplete.getPlace();

  • 1
    Can you show your ts.config? The problems can be that default angular ts.config has types: [] (an empty array). In that case you need to add 'googlemaps' to types. – Sherif Elmetainy Aug 26 '20 at 19:29
  • @SherifElmetainy i think its tsconfig.json file i have updated above for the reference. –  Aug 26 '20 at 19:39
  • On your screenshot it's not google.maps class, it's just types for it. And your error says that you haven't imported google maps to your component – vitaliy kotov Aug 26 '20 at 19:56
  • I already explained if have not imported in my component then why is it redirecting to when i use F12 to index.d.ts .. ? –  Aug 26 '20 at 21:17
  • @vitaliykotov it should show error in the typescript page as well .. ? –  Aug 26 '20 at 21:18
  • @Naman. Then the problem may be in tsconfig.app.json? – Sherif Elmetainy Aug 26 '20 at 21:37
  • @SherifElmetainy where can i find my tsconfig.app.json in angular 8 so that i can update the question .. –  Aug 27 '20 at 09:27
  • I have investigated how to use **agm** package and found this [example](https://stackblitz.com/edit/angular-google-maps-demo-geocoding?file=app/geocode.service.ts). So it seems that the problem is in compiler which can't find _google_ variable, although it's added by the package to the app. Thus you have to declare this variable like `declare var google: any;` – vitaliy kotov Aug 27 '20 at 20:20
  • @vitaliykotov i tried this as well it works on (new google.maps.Geocoder) and (new google.maps.places.Autocomplete(this.searchElementRef.nativeElement)) but in the (google.maps.places.PlaceResult = autocomplete.getPlace();) it gives the error of map not found. –  Aug 27 '20 at 21:21
  • @vitaliykotov i'll update the question again –  Aug 27 '20 at 21:21
  • I would suggest to try [this](https://stackoverflow.com/questions/56653284/how-to-fix-type-error-in-angular-google-maps) approach – vitaliy kotov Aug 28 '20 at 20:33
  • @vitaliykotov i've answered my own question and found the solution to it. –  Aug 29 '20 at 09:51

3 Answers3

29

Found the solution its in the tsconfig.app.json.

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

Added only "googlemaps" in the types which was missing and the error went away. No need to add declare var google: any; will work great without it.

  • 1
    For npm package `@angular/google-maps`, use : "types": ["google.maps"] – MrP Jan 27 '22 at 09:24
  • Also... in your app.module.ts, I had an incomplete import and needed to add " libraries: ['places']" to it: AgmCoreModule.forRoot({ // https://developers.google.com/maps/documentation/javascript/get-api-key?hl=en#key apiKey: '....', libraries: ['places'] – AppDreamer Jun 24 '22 at 21:05
3

Solution is

  1. install npm i @types/googlemaps@3.43.3"
  2. go to tsconfig.app.json and set the type to "types": ["googlemaps"]
vimuth
  • 5,064
  • 33
  • 79
  • 116
  • What Angular version you're at? I'm on v14, when `npm i @types/googlemaps` was told it's deprecated and auto-switching to `@types/google.maps`, and same **Cannot find name 'google'**. Tried your solution asked for `@types/googlemaps@3.43.3`, still the same. – Jeb50 Dec 14 '22 at 18:19
0

The following worked for my use case, using Node 16:

% node --version
v16.17.1
% npm --version
8.15.0

Installed the Angular Google Maps module and types:

npm i @angular/google-maps --legacy-peer-deps
npm i @types/googlemaps --legacy-peer-deps

Note, if you're running a more recent version of Node, you can probably leave off the --legacy-peer-deps argument.

Then, adding the Google Map type to the "types" directive in tsconfig.app.json:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [
      "google.maps" /* DECLARE TYPE HERE */
    ]
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

Finally able to make use of the Google Maps class:

new google.maps.Map(this.mapElement.nativeElement, {
    center: { lat: -34.397, lng: 150.644 },
    zoom: 8
});
leepowers
  • 37,828
  • 23
  • 98
  • 129