d3.js runtime error after upgrade to Angular 8
Asked Answered
D

2

14

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://mcmap.net/q/24681/-how-to-remove-global-quot-use-strict-quot-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?

Doble answered 31/5, 2019 at 18:55 Comment(2)
Possible duplicate of D3.js : Uncaught TypeError: Cannot read property 'document' of undefinedPatent
Hi @Reactgular, I did see that post and am trying to apply it to my situation. I have no idea how I would modify the babel options in my Angular project.Doble
W
19

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

Wager answered 2/6, 2019 at 21:55 Comment(4)
Thank you for this! I updated the targets and modules accordingly and now have a working application. I was receiving this error when setting the module to es2015, so I ended up setting it to commonjs. error TS1323: Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNext'.Doble
For me it was enought to change target from "es2015" to "es5".Orpah
That's not a solution, rather a workaround. With Angular 7 it was possible to target es2016/es2017 which obviously worked with d3. Now after upgrading to Angular 8 that no longer works. This either means that Angular 7 did not include d3 in compilation, but does so now in v8, or that Angular 8 has an issue.Ejaculation
I'm worried about side effects of these workaround... is there any proper solution for Angular 10?Homoio
W
0

I was able to get it working by including d3 in the "scripts" field of angular.json.

Weis answered 3/11, 2020 at 0:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.