Chartjs-Chart.js Angular error with data from .json file

0👍

Concern 1

As mentioned by @Stefan, move the this.createChart() in the subscribe() callback as the observable is asynchronous. By moving into the callback, it will guarantee the this.createChart() will be executed when the observable is returned.

this.fruitService.getFruits().subscribe((response) => {
  this.fruits = response.fruits;

  this.createChart();
});

Concern 2

I believe that you install chart.js with version 3 or later, which is incompatible with your current Chart.js configuration. From the documentation, xAxes and yAxes are no longer supported. Follow the instruction for the migration:

  • The xAxes and yAxes arrays were removed and axis options are individual scales now keyed by scale ID

  • legend, title and tooltip namespaces were moved from options to options.plugins

And to render the chart from the component (back-code), you should work with @ViewChild decorator.

Your code should be as below:

Component

import { ElementRef, ViewChild } from '@angular/core';
import { ChartOptions } from 'chart.js';

@ViewChild('baseChart', { static: true })
  canvasElem: ElementRef<HTMLCanvasElement>;

  createChart() {
    if (this.chart) {
      this.chart.destroy();
    }

    // Extract the labels and data from the fruits array
    const labels = this.fruits.map((fruit: any) => fruit.fruit);
    const data = this.fruits.map((fruit: any) => fruit.amountBought);

    const ctx = this.chart.nativeElement.getContext('2d');
    this.chart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: labels,
        datasets: [
          {
            data: data,
            borderColor: '#3cba9f',
            fill: false,
          },
          {
            data: data,
            borderColor: '#ffcc00',
            fill: false,
          },
        ],
      },

      options: {
        plugins: {
          legend: {
            display: false,
          },
        },
        scales: {
          x: {
            display: true,
          },

          y: {
            display: true,
            ticks: {
              beginAtZero: true,
            },
          },
        },
      } as ChartOptions<'line'>,
    });
  }

HTML

<canvas #baseChart class="chart"></canvas>

Demo @ StackBlitz

0👍

I made the code work with help from you guys! Thank you so much!
Here is the working code:

import { Chart } from 'chart.js/auto';

import { Component, OnInit } from '@angular/core';

import { Fruit } from './fruit.model';
import { FruitService } from './fruit.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  title = 'angular-fetch-json-data';
  public fruits: Fruit[];
  public chart: any;

  public constructor(private fruitService: FruitService){
  }

  public ngOnInit(): void {
    this.fruitService.getFruits().subscribe((response) => {
      this.fruits = response.fruits;
      this.createChart();
    })
  }

  createChart() {
    if (this.chart) {
      this.chart.destroy();
    }

    // Extract the labels and data from the fruits array
    const labels = this.fruits.map((fruit: any) => fruit.fruit);
    const data = this.fruits.map((fruit: any) => fruit.amountBought);

    
    this.chart = new Chart('canvas', {
      type: 'line', 
      data: {
        labels: labels,
        datasets: [
          {
            data: data,
            borderColor: '#3cba9f', 
            fill: false 
          },
        ]
      },
      options: {
        scales: {
          xAxes: {
            display: true
          },
          yAxes: {
            display: true,
              beginAtZero: true
            
          }
        }
      }
    });
  }
}

Leave a comment