0

I am trying to integrate google map in ionic 4 application, and unfortunately facing nativeElement not found error.

@ViewChild('Map') mapElement: ElementRef; ~~~~~~~~~~~~~~~~

node_modules/@angular/core/core.d.ts:8436:47 8436 (selector: Type | Function | string, opts: { ~~~~~~~ 8437 read?: any; ~~~~~~~~~~~~~~~~~~~ 8438 static: boolean; ~~~~~~~~~~~~~~~~~~~~~~~~ 8439 }): any; ~~~~~ An argument for 'opts' was not provided. System console .

home.page.ts

import {Component, ElementRef, NgZone, ViewChild, OnInit} from '@angular/core';
import {Geolocation} from '@ionic-native/geolocation/ngx';

declare var google: any;
@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
    @ViewChild('Map') mapElement: ElementRef;
    map: any;
    mapOptions: any;
    location = {lat: null, lng: null};
    markerOptions: any = {position: null, map: null, title: null};
    marker: any;
    apiKey: any = 'API_KEY'; 

  constructor(public zone: NgZone, public geolocation: Geolocation) {
    /*load google map script dynamically */
      const script = document.createElement('script');
      script.id = 'googleMap';
      if (this.apiKey) {
          script.src = 'https://maps.googleapis.com/maps/api/js?key=' + this.apiKey;
      } else {
          script.src = 'https://maps.googleapis.com/maps/api/js?key=';
      }
      document.head.appendChild(script);
      /*Get Current location*/
      this.geolocation.getCurrentPosition().then((position) =>  {
          this.location.lat = position.coords.latitude;
          this.location.lng = position.coords.longitude;
      });
      /*Map options*/
      this.mapOptions = {
          center: this.location,
          zoom: 21,
          mapTypeControl: false
      };
      setTimeout(() => {
          this.map = new google.maps.Map(this.mapElement.nativeElement, this.mapOptions);
          /*Marker Options*/
          this.markerOptions.position = this.location;
          this.markerOptions.map = this.map;
          this.markerOptions.title = 'My Location';
          this.marker = new google.maps.Marker(this.markerOptions);
      }, 3000);
  }

}

2 Answers2

1

We can set static to true if you have a situation where we need to access the view query result before the ngAfterVewInit hook is called. However setting true allow access the view query results from ngOnInit lifecycle.

Latest version Angular, @ViewChild has 2 parameters

@ViewChild(‘Map’, {static: true}) mapElement: ElementRef;
JohnMathew
  • 508
  • 1
  • 5
  • 21
  • Please explain that how your answer will help to solve the problem, and just don't give code only answer without context. – Arun Vinoth-Precog Tech - MVP Jan 15 '20 at 15:46
  • this couldn't resolve the issue - the error is in the line (@ViewChild(‘Map’, {static: true}) mapElement: ElementRef;) - error - var Map: MapConstructor Invalid character.ts(1127) Invalid character. – Ebrahim Mithaiwala Jan 16 '20 at 04:53
0

Newer versions of Angular require you to provide an object as a second parameter to the @ViewChild decorator (docs). That object needs to have a boolean value for static.

// {static: boolean}
@ViewChild('Map', {static: false) mapElement: ElementRef;

Deciding ifstatic should be true or false comes down to whether or not you are dynamically rendering the element in your template, like with *ngIf or *ngFor. If you're not using those (or any other structural directives), you should set static to false so that you can access the element as soon as possible.

Speaking of when you can access the element reference, you have a lot of logic in your component constructor. It is highly recommended that you move it out of the constructor and into a lifecycle hook. You will absolutely need to move any code referencing mapElement out of the constructor as it will always be undefined there (this might be why you are using a setTimeout?). ElementRefs with {static:false} will be available in ngOnInit, whereas ElementRefs with {static:true} will be available in ngAfterViewInit.

Since you are using Ionic, it would also be good for you to have a look at their lifecycle hooks as well.

Chris Newman
  • 3,152
  • 1
  • 16
  • 17
  • this couldn't resolve the issue - the error is in the line (@ViewChild(‘Map’, {static: true}) mapElement: ElementRef;) - error - var Map: MapConstructor Invalid character.ts(1127) Invalid character. – Ebrahim Mithaiwala Jan 16 '20 at 04:57
  • this answer solves the error in your original question. you can provide more information in your post or open a new question regarding this new error. Sounds like a syntax error though – Chris Newman Jan 16 '20 at 14:35