skip to Main Content

I’m building a Twitter-type application with a Typescript/Angular2 front-end framework and a Node.js back-end. I’m following the code from Levi Botelho’s Angular 2 Projects video tutorial, though I am not using his Gulpfile but instead running the application using systemjs.config.js.

I am injecting Chart.js into my systemjs.config.js file and I am also including a in index.html. However, I can’t make Chart.js work in my application, I keep trying different solutions and I keep getting errors in my browser console. I have all the Chart.js files in my ./node_modules folder.

I will show the different variations I’ve tried and the error messages I’ve received, but here is the code in index.html and systemjs.config.js that works without Chart.js:

index.html

<html>
  <head>
    <title>Angular 2 Twitter</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous" />
    <!-- inject:css -->
    <!-- endinject -->
    <script src="/socket.io/socket.io.js"></script>
    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
  </head>
  <body>

    <script src="/frontend/systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>

    <app>Loading...</app>
    <!-- inject:js -->
    <!-- endinject -->
  </body>
</html>

systemjs.config.js

(function (global) {
  System.config({
    paths: {
      // paths serve as alias
      'npm:': 'node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      app: 'app',
      // angular bundles
      '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
      '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
      '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
      '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
      '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
      '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
      '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
      // other libraries
      'rxjs':                      'npm:rxjs',
      'moment':                     'npm:moment',
      'socket.io-client':           'npm:socket.io-client',
      'angular-in-memory-web-api': 'npm:angular-in-memory-web-api',
      'chart.js':                   'npm:chart.js'
    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      app: {
        main: './main.js',
        defaultExtension: 'js'
      },
      'rxjs': {
        defaultExtension: 'js'
      },
      'moment': {
        main: './moment.js',
        defaultExtension: 'js'
      },
      'socket.io-client': {
        main: './socket.io.js',
        defaultExtension: 'js'
      },
      'angular-in-memory-web-api': {
        main: './index.js',
        defaultExtension: 'js'
      }
    }
  });
})(this);

EDIT: Added to question later — And this is my app.module.ts file:

import {NgModule} from "@angular/core";
import {BrowserModule} from "@angular/platform-browser";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import AppComponent from "./app.component";
import TwitterService from "./twitter.service";
import BarGraphComponent from "./bar-graph.component";
import LineGraphComponent from "./line-graph.component";

@NgModule({
    imports: [BrowserModule, FormsModule, HttpModule],
    declarations: [AppComponent, BarGraphComponent, LineGraphComponent],
    bootstrap: [AppComponent],
    providers: [TwitterService]
})
export default class AppModule { }

EDIT – Also added to question later — Here is my package.json file:

{
  "name": "angular-2-twitter",
  "version": "1.0.0",
  "scripts": {
    "start": "nodemon server.js",
    "typings": "typings"
  },
  "devDependencies": {
    "browser-sync": "^2.16.0",
    "browserify": "^13.1.0",
    "gulp": "^3.9.1",
    "gulp-cached": "^1.1.0",
    "gulp-concat": "^2.6.0",
    "gulp-htmlmin": "^2.0.0",
    "gulp-if": "^2.0.1",
    "gulp-inject": "^4.1.0",
    "gulp-sass": "^2.3.2",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-tslint": "^6.1.1",
    "gulp-uglify": "^2.0.0",
    "lite-server": "^2.2.2",
    "tsify": "^1.0.7",
    "tslint": "^3.15.1",
    "typescript": "^1.8.10",
    "concurrently": "^3.0.0",
    "typings": "^1.4.0",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0",
    "watchify": "^3.7.0",
    "yargs": "^5.0.0"
  },
  "dependencies": {
    "@angular/common": "~2.0.1",
    "@angular/compiler": "~2.0.1",
    "@angular/core": "~2.0.1",
    "@angular/forms": "~2.0.1",
    "@angular/http": "~2.0.1",
    "@angular/platform-browser": "~2.0.1",
    "@angular/platform-browser-dynamic": "~2.0.1",
    "@angular/router": "~3.0.1",
    "@angular/upgrade": "~2.0.1",
    "angular-in-memory-web-api": "~0.1.1",
    "bootstrap": "^3.3.7",
    "chart.js": "^2.2.2",
    "compression": "^1.6.2",
    "core-js": "^2.4.1",
    "express": "^4.14.0",
    "moment": "^2.15.0",
    "reflect-metadata": "^0.1.8",
    "requirejs": "^2.3.2",
    "rxjs": "5.0.0-beta.12",
    "socket.io-client": "^1.4.8",
    "systemjs": "0.19.39",
    "twit": "^2.2.4",
    "zone.js": "^0.6.25"
  }
}

Here is one of two chart files I am trying to include in my code, the second one is very similar to this:

bar-graph.component.ts

import {Component, ElementRef, Input, AfterViewInit, ViewChild} from '@angular/core';
import * as Chart from "chart.js";

@Component({
    selector: "bar-graph",
    templateUrl: "/app/graph.component.html"
})

export default class BarGraphComponent implements AfterViewInit {
    @ViewChild("canvas") private canvas: ElementRef;
    @Input() private data: Array<number>;
    @Input() private labels: Array<string>;

    ngAfterViewInit(){
        const chart = new Chart(this.canvas.nativeElement.getContext("2d"), {
            type: "bar",
            data: {
                labels: this.labels,
                datasets: [{
                    label: "Count",
                    data: this.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)",
                        "rgba(255, 99, 132, 0.2)",
                        "rgba(54, 162, 235, 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)",
                        "rgba(255,99,132,1)",
                        "rgba(54, 162, 235, 1)"
                    ],
                    borderWidth: 1
                }]
            },
            options: {
                legend: {
                    display: false
                },
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true
                        }
                    }]
                }
            }
        });

        setInterval(function () {
            (chart as any).update();
        }, 1000);
    }
}

Then I start to include Chart.js into my code and I get errors. When I add Chart.js into systemjs.config.js like so:

 'chart.js': {
    main: './src/chart.js',
    defaultExtension: 'js'
  }

Then I get this error:

enter image description here

So then in systemjs.config.js I include chartjs-color:

 map: {
     .......
     'chart.js':                   'npm:chart.js',
     'chartjs-color':              'npm:chartjs-color'
 }
 packages: {
      ......
      'chartjs-color': {
          main: './index.js',
          defaultExtension: 'js'
       }
  }

So then I get this, and thus begins the rabbit hole of trying to find a solution in systemjs.config.js

enter image description here

So then I remove chartjs-color from systemjs.config.js because I don’t inject it anyway, and per the accepted answer to this StackOverflow question I included this line in my index.html file:

<script src="node_modules/chart.js/dist/Chart.bundle.js"></script>

I get this:

enter image description here

So I add the chartjs-color link to my index.html file, and I get this:

enter image description here

At this point, I have given up. Any advice on how to fix this issue is greatly appreciated.

2

Answers


  1. you need to import ChartsModule as shown below in @NgModule,

    import { ChartsModule } from 'ng2-charts/ng2-charts';
    
    // In your App's module:
    @NgModule({
      imports: [
         ChartsModule
      ]
      ...
    })
    

    More Info : https://github.com/valor-software/ng2-charts/blob/master/demo/index.ts

    NOTE : change 'chart.js':'npm:chart.js' to appropriate name like ng2-charts for simplicity as shown here in systemjs.config.js : http://plnkr.co/edit/7fGsiuRjcF0M0Ffeoml2?p=preview.

    Login or Signup to reply.
  2. I use Chart.js in an Angular 2 app, and it works without having to add chartjs-color paths to my system.config.js

    First:

    • npm --version

    If the version is not at least 3.x.x, upgrade to the latest Node/npm, then:

    • npm --version and see that it’s 3+
    • npm install
    • npm rebuild

    Check again. If you still get the error in the OP:

    • npm install chartjs-color chartjs-color-string

    More info about my setup:

    This is my working Chart.js configuration in systemjs.config.js

    paths: {'npm:' : 'node_modules/'},
    
    map: {'chart.js' : 'npm:chart.js'},
    
    packages: { 'chart.js' : { main:'./dist/Chart.js', defaultExtension: 'js'} }
    

    This is how I import the library in my custom directive:

    import 'chart.js';
    

    From there, I can use the Chart object. To prevent Typescript from raising errors, I also have a custom.typings.d.ts file which contains:

    declare var Chart:any;
    

    This definition file holds a few custom definitions relevant to my app. I added a reference to these definitions in main.ts, with:

    ///<reference path="relative/path/to/custom.typings.d.ts"/>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search