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:
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
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:
So I add the chartjs-color link to my index.html
file, and I get this:
At this point, I have given up. Any advice on how to fix this issue is greatly appreciated.
2
Answers
you need to import
ChartsModule
as shown below in@NgModule
,More Info : https://github.com/valor-software/ng2-charts/blob/master/demo/index.ts
NOTE : change
'chart.js':'npm:chart.js'
to appropriate name likeng2-charts
for simplicity as shown here insystemjs.config.js
: http://plnkr.co/edit/7fGsiuRjcF0M0Ffeoml2?p=preview.I use
Chart.js
in anAngular 2
app, and it works without having to addchartjs-color
paths to mysystem.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’s3+
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
This is how I import the library in my custom directive:
From there, I can use the
Chart
object. To prevent Typescript from raising errors, I also have acustom.typings.d.ts
file which contains:This definition file holds a few custom definitions relevant to my app. I added a reference to these definitions in
main.ts
, with: