最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular 4 cannot read property nativeElement of undefined using ViewChild - Stack Overflow

programmeradmin7浏览0评论

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
Add a ment  | 

4 Answers 4

Reset to default 1

Your 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;
发布评论

评论列表(0)

  1. 暂无评论