ViewChildren from http - undefined


#1

At the parent html:

<doughnut-chart #chartData *ngFor="let ansd of answersData;"></doughnut-chart>

parent ts:
@ViewChildren("chartData") private chartDataList: QueryList<ElementRef>;

It is function activated by button

getAnswersReport(timeFrame){
        this.managerService.getAnswersReport().subscribe((resp) => {
            this.answersData = JSON.parse(resp.text());
           **this.chartDataList.changes.subscribe(chartData => {**
**                this.answersData[0]**
**            //     if(chartData)**
**            //         chartData.last.nativeElement.focus();**
**            //         console.log("chart data changed");**
**            });**
        }, (err) => {
            let toast = this.toastCtrl.create({
                message: "Problem getting the data for manager getAnswersReport. Contact administrator.",
                duration: 3000,
                position: 'top'
            });
            toast.present();
        });
    }

at the child :

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

/**
 * Generated class for the DoughnutChartComponent component.
 *
 * See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html
 * for more info on Angular Components.
 */
@Component({
  selector: 'doughnut-chart',
  templateUrl: 'doughnut-chart.html'
})
export class DoughnutChartComponent {
  doughnutChart: any;
 
 @Input() chartData: any ;
 @ViewChild('doughnutCanvas') doughnutCanvas;
  text: string;

  constructor() {
    console.log(JSON.stringify(this.chartData));
    this.text = 'Hello World';
  }

  ionViewDidLoad(){
    this.doughnutChart = new Chart(this.doughnutCanvas.nativeElement, {
      //this.answersData
              type: 'doughnut',
              data: {
                  labels: this.chartData.label,
                  datasets: [{
                      label: '# of Votes',
                      data: this.chartData.data,
                      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)'
                      ],
                      hoverBackgroundColor: [
                          "#FF6384",
                          "#36A2EB",
                          "#FFCE56",
                          "#FF6384",
                          "#36A2EB",
                          "#FFCE56"
                      ]
                  }]
              }
  
          });
  }

}

CHILD HTTML

<ion-card>
  <ion-card-header >
    <input #doughnutCanvasHeader placeholder="Your question title">
  </ion-card-header>
  <ion-card-content>
    <canvas #doughnutCanvas></canvas>
    {{text}}
  </ion-card-content>  

</ion-card>

the problem is that chartData arrives undefined.
How to init it not in IonViewDidLoad (ngAfterInit) - at this stage the data is not there yet
but in the resolve of the http subscribe function… IN this case - getAnswersReport

Really need a fast solution…


#2

Hello, is

this.chartDataList.changes.subscribe(chartData => 

this triggered?

Best regards, anna-liebt


#3

It did return QueryList with result of 7 items, but i couldn’t connect/init to the chartData input inside the children.
So it showed the charts but empty.

So what I did was simpler , just used set , which appears to be async
So when at the end the answers report comes it initializes the charts children.

In charts.html

<ion-row>
    <ion-col *ngFor="let ansd of answersData;">
      <doughnut-chart  [chartData]="ansd"></doughnut-chart> 
    </ion-col>
    
  </ion-row>

In charts.ts

I have a function async bringing the data to show in charts and I don’t know exactly when it returns.

 getAnswersReport(){
        this.managerService.getAnswersReport().subscribe((resp) => {
            this.answersData = JSON.parse(resp.text());
          
        }, (err) => {
          
            let toast = this.toastCtrl.create({
                message: "Problem getting the data for manager getAnswersReport. Contact administrator.",
                duration: 3000,
                position: 'top'
            });
            toast.present();
        });
    }

In child doughnut-chart.html

  <ion-label #doughnutCanvasHeader placeholder="Your question title">
    {{myChartData.QuestionDesc}}
  </ion-label>
  <ion-item>
    <canvas #doughnutCanvas></canvas>
  </ion-item>

In doughnut-chart.ts

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




@Component({
  selector: 'doughnut-chart',
  templateUrl: 'doughnut-chart.html',
  inputs: ['chartData']
})
export class DoughnutChartComponent {
  doughnutChart: any;
  myChartData:any;

  @ViewChild('doughnutCanvas') doughnutCanvas;
  

  constructor() {}

  set chartData(value) {
    if (value) {
      this.myChartData= value;
      
      this.doughnutChart = new Chart(this.doughnutCanvas.nativeElement, {
        //this.answersData
        type: 'doughnut',
        data: {
          labels: this.myChartData.label,
          datasets: [{
            label: '# of Votes',
            data: this.myChartData.data,
            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)'
            ],
            hoverBackgroundColor: [
              "#FF6384",
              "#36A2EB",
              "#FFCE56",
              "#FF6384",
              "#36A2EB",
              "#FFCE56"
            ]
          }]
        }

      });
    }
  }
}

Thanks for help.
I hope this post will help someone else pulling his hear right now :slight_smile: