I am simply trying to access an element within my Angular 4 template to place a Google Map but I keep getting a "cannot read property native element of undefined" error. I've seen other people asking similar questions but anything I've tried up to this point has not worked.
I get the same error when trying to access the element in both ngOnInit
and ngAfterViewInit
. I also tried using document.getElementById
and that gives me a null error as well. I know its not a Google Maps error because I get the error trying to access the element outside of Google Maps.
I have the following inside homeponent.ts (this is inside a specific home ponent, not within the main app module):
import { NgModule, Component, OnInit, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
import { } from '@types/googlemaps';
@Component({
selector: 'home-page',
templateUrl: './home.html'
})
export class HomeComponent implements OnInit, AfterViewInit {
@ViewChild('gmap') el:ElementRef;
map: google.maps.Map;
public ngOnInit() {
// other ponent initialization code here
}
public ngAfterViewInit () {
let mapProp = {
center: new google.maps.LatLng(18.5793, 73.8143),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map(this.el.nativeElement, mapProp);
// this alone gives me the same error
setTimeout(() => {
console.log(this.el.nativeElement);
}, 0);
}
}
Inside the ponent template - homeponent.html:
<div class="row">
<div class="col-md-12">
<div class="text-center">
<div #gmap style="width:100%;height:400px"></div>
</div>
</div>
</div>
I am simply trying to access an element within my Angular 4 template to place a Google Map but I keep getting a "cannot read property native element of undefined" error. I've seen other people asking similar questions but anything I've tried up to this point has not worked.
I get the same error when trying to access the element in both ngOnInit
and ngAfterViewInit
. I also tried using document.getElementById
and that gives me a null error as well. I know its not a Google Maps error because I get the error trying to access the element outside of Google Maps.
I have the following inside home.ponent.ts (this is inside a specific home ponent, not within the main app module):
import { NgModule, Component, OnInit, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
import { } from '@types/googlemaps';
@Component({
selector: 'home-page',
templateUrl: './home.html'
})
export class HomeComponent implements OnInit, AfterViewInit {
@ViewChild('gmap') el:ElementRef;
map: google.maps.Map;
public ngOnInit() {
// other ponent initialization code here
}
public ngAfterViewInit () {
let mapProp = {
center: new google.maps.LatLng(18.5793, 73.8143),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map(this.el.nativeElement, mapProp);
// this alone gives me the same error
setTimeout(() => {
console.log(this.el.nativeElement);
}, 0);
}
}
Inside the ponent template - home.ponent.html:
<div class="row">
<div class="col-md-12">
<div class="text-center">
<div #gmap style="width:100%;height:400px"></div>
</div>
</div>
</div>
Share
Improve this question
edited Mar 7, 2018 at 20:52
Ikhlak S.
9,05611 gold badges59 silver badges79 bronze badges
asked Mar 7, 2018 at 0:23
bschmittybschmitty
1,2183 gold badges21 silver badges49 bronze badges
0
4 Answers
Reset to default 1Your ponent's templateUrl says './home.html'
but you also mentioned the file name being home.ponent.html
in "Inside the ponent template - home.ponent.html
". Maybe that's your problem?
I had a loader on the page that was showing until all the data was returning on the page:
public getData() {
this.loading = true;
this.homeService.getData().subscribe(response => {
this.resort = response;
this.loading = false;
this.error = false;
this.getMap();
}, error => {
this.loading = false;
this.error = true;
});
}
So even though ngAfterViewInit was running, the data from the database still wasn't back by the time that function ran, which was why it wasn't able to find the element as the actual data was hidden from an *ngIf until this.loading was false. So to correct I'm just calling getMap() once the data has been returned, rather then in the AfterViewInit function.
I then had to wrap that getMap function in a setTimeout to ensure the *ngIf was loading the content data before I was trying to access the element as well:
public getMap() {
setTimeout(() => {
// accessing element here
});
}
Perhaps because HomeComponent
has no @Component
annotation?
For one thing, without @Component
, there's no way for HomeComponent
to know that home.ponent.html is its template, and if it doesn't know its template, it doesn't know #gmap
is a view child. Simply matching templates to classes by naming convention or file location isn't enough.
Change the type to any
@ViewChild('gmap') el: any;