Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3.js runtime error after upgrade to Angular 8

I am experimenting with upgrading my Angular 6 application to Angular 8. My code compiles, but I immediately receive a run-time error "d3.js:8 Uncaught TypeError: Cannot read property 'document' of undefined".

The line failing in d3.js is var d3_document = this.document;. This leads me to believe that Angular 8 is running d3.js in strict mode. I have the latest version of the d3 node module ("d3": "3.5.17"), and it apparently does not support strict mode; my understanding is "this" is supposed to reference the window object but that does not work in strict mode.

I know Angular 8 now uses dart-sass instead of node-sass, which is supposedly stricter. I did try installing node-sass to use it instead of dart-sass (as recommended by the upgrade documentation), but I am pretty sure this is not sass related.

I will note that some of my other packages need to be updated because they are dependent on Angular 6's packages, but I don't see how this would effect his d3 error.

I have also tried explicitly saying "noImplicitUseStrict": false, in my tsconfig.json file, but received the same error. I have also tried "noImplicitUseStrict": true, with no luck.

I have referenced this stack overflow post which addresses the same error: D3.js : Uncaught TypeError: Cannot read property 'document' of undefined, and the referenced solution: https://stackoverflow.com/questions/33821312/how-to-remove-global-use-strict-added-by-babel; but I am having a difficult time applying these to my situation because I am working with an Angular project and unsure if babel applies or how to modify the babel options.

Full Error:

d3.js:8 Uncaught TypeError: Cannot read property 'document' of undefined
    at d3.js:8
    at Object../node_modules/d3/d3.js (d3.js:9554)
    at __webpack_require__ (bootstrap:83)
    at Module../dist/core-services/fesm2015/core-services.js (core-services.js:1)
    at __webpack_require__ (bootstrap:83)
    at Module../src/app/app.component.ts (main-es2015.js:22262)
    at __webpack_require__ (bootstrap:83)
    at Module../src/app/app.module.ts (app.component.ts:21)
    at __webpack_require__ (bootstrap:83)
    at Module../src/main.ts (main.ts:1)
(anonymous) @   d3.js:8
./node_modules/d3/d3.js @   d3.js:9554
__webpack_require__ @   bootstrap:83
./dist/core-services/fesm2015/core-services.js  @   core-services.js:1
__webpack_require__ @   bootstrap:83
./src/app/app.component.ts  @   main-es2015.js:22262
__webpack_require__ @   bootstrap:83
./src/app/app.module.ts @   app.component.ts:21
__webpack_require__ @   bootstrap:83
./src/main.ts   @   main.ts:1
__webpack_require__ @   bootstrap:83
0   @   main.ts:17
__webpack_require__ @   bootstrap:83
checkDeferredModules    @   bootstrap:45
webpackJsonpCallback    @   bootstrap:32
(anonymous) @   main-es2015.js:1

Expected no error. Is there a way to specify that I do not want this node module to run in strict mode?

like image 890
troyprince1243 Avatar asked May 31 '19 18:05

troyprince1243


People also ask

Does D3 js work with angular?

Getting data from a JSON APID3 natively supports JSON data, so it makes it really easy to integrate with your Angular application. First, you'll need a JSON API endpoint or file.

Do people still use D3 JS?

The JavaScript ecosystem has completely changed during this time, in terms of libraries, best practices and even language features. Nevertheless, D3 is still here. And it's more popular than ever.

Is D3 JS frontend or backend?

js is a frontend framework that allows you to make dynamic web application in javascript in the browser. d3. js is to create visualizations such as graphs or charts in the browser.


1 Answers

I have just experienced the same issue since yesterday morning, but I have now fixed it.

Within my package.json I use the following packages:

"d3": "^3.5.17",
"ng2-nvd3": "^2.0.0",
"nvd3": "^1.8.6"

The real problem here is that the D3 libraries are not ready for ES2015/ES6.

So to fix this, you need to change 2 items within your Angular solution's tsconfig.json file.

module = es2015 and NOT esnext

target = es5 and NOT es2015

So the full tsconfig.json should look like this:

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "importHelpers": true,
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

To see charts in action, take a look at my tutorial here: http://www.exodus-cloud.co.uk/tutorials/angular-charting-nvd3

like image 91
Huw Roberts Avatar answered Sep 17 '22 15:09

Huw Roberts