Ionic/Chart.js - Cannot read property 'nativeElement' of undefined
Asked Answered
T

4

6

I have a simple project that displays an Ionic segment in which there is a Chart.js barchart. I have no problem with displaying the chart itself, but trying to put the chart HTML inside Ionic segment gives me the following error:

ERROR TypeError: Cannot read property 'nativeElement' of undefined
    at HomePage.webpackJsonp.203.HomePage.ionViewDidLoad (home.ts:19)

If I just move <canvas #barcanvas></canvas> and place it almost anywhere else in the .html document, the chart displays nicely, but not inside the Ionic segment element.

home.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <div padding>
    <ion-segment [(ngModel)]="pet">
      <ion-segment-button value="kittens">
        Kittens
      </ion-segment-button>
      <ion-segment-button value="puppies">
        Puppies
      </ion-segment-button>
    </ion-segment>
  </div>

  <div [ngSwitch]="pet">
    <ion-list *ngSwitchCase="'puppies'">
      puppies...
      <canvas #barcanvas></canvas>
    </ion-list>

    <ion-list *ngSwitchCase="'kittens'">
      kittens...
    </ion-list>
  </div>
</ion-content>

home.ts

import { Component, ViewChild } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Chart } from 'chart.js';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  @ViewChild('barcanvas') barcanvas;
  barChart: any;

  constructor(public navCtrl: NavController) {

  }

  ionViewDidLoad() {

    this.barChart = new Chart(this.barcanvas.nativeElement, {

      type: 'bar',
      data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
        datasets: [{
          label: '# of Votes',
          data: [12, 19, 3, 5, 2, 3],
          backgroundColor: [
            'rgba(255, 99, 132, 0.2)',
            'rgba(54, 162, 235, 0.2)',
            'rgba(255, 206, 86, 0.2)',
            'rgba(75, 192, 192, 0.2)',
            'rgba(153, 102, 255, 0.2)',
            'rgba(255, 159, 64, 0.2)'
          ],
          borderColor: [
            'rgba(255,99,132,1)',
            'rgba(54, 162, 235, 1)',
            'rgba(255, 206, 86, 1)',
            'rgba(75, 192, 192, 1)',
            'rgba(153, 102, 255, 1)',
            'rgba(255, 159, 64, 1)'
          ],
          borderWidth: 1
        }]
      }

    });

  }
}
Titanium answered 20/1, 2019 at 18:23 Comment(0)
M
0

In home.ts you are loading the bar in ionViewDidLoad so if u wanted to put it in such way , u can't put it in the segment since the segment will not be able to read the ionViewDidLoad inner data since segment is also being loaded after the ionViewDidLoad function is executed,else if you want to put it in the segment, you should take the data out from the ionViewDidLoad() and put them in other function and therefore u could put the function directly in segment and thus the function could be readable by the segment.

Monthly answered 20/1, 2019 at 18:40 Comment(3)
<ion-list (onCreate)="nameofurfunction()" *ngSwitchCase="'list'"> Listing </ion-list>Monthly
Now the problem is that the graph doesn't show up even if this piece of code fixes the error.Titanium
I wanted to ask you, why did you put fromthe begining the code in ionload, why didn't you put it direct in constructor.Try to put ur xode from function and put it direct in the constructor.Monthly
F
5

If you are working with Angular >=8, now you have to pass a second parameter to Viewchild for options and set static: true

@ViewChild('barcanvas', {static: true}) barcanvas;
Fierce answered 30/3, 2020 at 20:19 Comment(1)
While the chart works fine, ng test fails.Semipostal
M
0

In home.ts you are loading the bar in ionViewDidLoad so if u wanted to put it in such way , u can't put it in the segment since the segment will not be able to read the ionViewDidLoad inner data since segment is also being loaded after the ionViewDidLoad function is executed,else if you want to put it in the segment, you should take the data out from the ionViewDidLoad() and put them in other function and therefore u could put the function directly in segment and thus the function could be readable by the segment.

Monthly answered 20/1, 2019 at 18:40 Comment(3)
<ion-list (onCreate)="nameofurfunction()" *ngSwitchCase="'list'"> Listing </ion-list>Monthly
Now the problem is that the graph doesn't show up even if this piece of code fixes the error.Titanium
I wanted to ask you, why did you put fromthe begining the code in ionload, why didn't you put it direct in constructor.Try to put ur xode from function and put it direct in the constructor.Monthly
B
0

ionViewDidLoad() dont use this. Just use this : ionViewDidEnter().

Bloch answered 5/9, 2019 at 2:38 Comment(0)
F
0

Another possible answer if someone is having this issue : in the template if the chart canvas is within a condition (if, ng-template, switch, etc), it might not find the nativeElement. You can put a timer to give the time to the browser to resolve it. Ex in a .ts file :

setTimeout(() => {
  this.ionViewDidLoad();
}, 50);

In this present issue the canvas is within a switch case.

Faythe answered 26/9, 2023 at 17:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.