Search code examples
javascriptangulartypescripttensorflowdanfojs

How to import and use Tensorflow's DANFO.js library inside an Angular web app?


I am trying to use Tensorflow's DANFO.js library inside an Angular web app (with Ionic component's but that is irelevant).

  • I simply ran the command: npm install danfojs --save and npm install @tensorflow/tfjs-node --save
  • I tried all kinds of imports inside an Angular Service like: import 'danfojs';, import { DataFrame } from 'danfojs'; or even according to only related question to this topic I could find:import { DataFrame } from 'danfojs/dist/core/frame';
  • All of the above examples don't work
  • I even tried importing the DANFO.js in app.module without any change

And I always get this error message (rest of the error is in edit):

Build at: 2021-11-21T21:38:12.984Z - Hash: 5f05ff4be188e54ccaaf - Time: 10137ms
[ng] Error: node_modules/danfojs/types/core/generic.d.ts:75:26 - error TS2307: Cannot find module '@tensorflow/tfjs-node' or its corresponding type declarations.    
[ng] 75     get tensor(): import("@tensorflow/tfjs-node").Tensor1D | import("@tensorflow/tfjs-node").Tensor2D;
[ng]                             ~~~~~~~~~~~~~~~~~~~~~~~
[ng] Error: node_modules/danfojs/types/core/generic.d.ts:75:69 - error TS2307: Cannot find module '@tensorflow/tfjs-node' or its corresponding type declarations.    
[ng] 75     get tensor(): import("@tensorflow/tfjs-node").Tensor1D | import("@tensorflow/tfjs-node").Tensor2D;

How can I use DANFO.js inside an Angular app (specifically inside an service)?


Edit:

I added code to tsconfig.js according to the answer below, unfortunately the error persists. This is my tsconfig.js file:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": ["es2018", "dom"],
    "skipLibCheck": true
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

The whole error code gets so long it doesn't fit VS Code terminal (there are just hundreds of errors):

[ng] 84     to_csv(options?: CsvOutputOptionsNode): string | void;
[ng]               ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:84:20 - error TS1109: Expression expected.
[ng] 84     to_csv(options?: CsvOutputOptionsNode): string | void;
[ng]                       ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:84:22 - error TS2693: 'CsvOutputOptionsNode' only refers to a type, but is being used as a value here.
[ng] 84     to_csv(options?: CsvOutputOptionsNode): string | void;
[ng]                         ~~~~~~~~~~~~~~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:84:43 - error TS1005: ';' expected.
[ng] 84     to_csv(options?: CsvOutputOptionsNode): string | void;
[ng]                                              ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:84:45 - error TS2693: 'string' only refers to a type, but is being used as a value here.
[ng] 84     to_csv(options?: CsvOutputOptionsNode): string | void;
[ng]                                                ~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:84:54 - error TS2532: Object 
is possibly 'undefined'.
[ng] 84     to_csv(options?: CsvOutputOptionsNode): string | void;
[ng]                                                         ~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:84:58 - error TS1109: Expression expected.
[ng] 84     to_csv(options?: CsvOutputOptionsNode): string | void;
[ng]                                                             ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:85:5 - error TS2304: Cannot find name 'to_json'.
[ng] 85     to_json(options?: {
[ng]        ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:85:13 - error TS2304: Cannot 
find name 'options'.
[ng] 85     to_json(options?: {
[ng]                ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:85:21 - error TS1109: Expression expected.
[ng] 85     to_json(options?: {
[ng]                        ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:86:18 - error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
[ng] 86         format?: "row" | "column";
[ng]                     ~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:86:26 - error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
[ng] 86         format?: "row" | "column";
[ng]                             ~~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:86:34 - error TS1005: ',' expected.
[ng] 86         format?: "row" | "column";
[ng]                                     ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:87:20 - error TS2693: 'string' only refers to a type, but is being used as a value here.
[ng] 87         filePath?: string;
[ng]                       ~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:87:26 - error TS1005: ',' expected.
[ng] 87         filePath?: string;
[ng]                             ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:88:7 - error TS1005: ';' expected.
[ng] 88     }): object | void;
[ng]          ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:88:9 - error TS2304: Cannot find name 'object'.
[ng] 88     }): object | void;
[ng]            ~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:88:18 - error TS2532: Object 
is possibly 'undefined'.
[ng] 88     }): object | void;
[ng]                     ~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:88:22 - error TS1109: Expression expected.
[ng] 88     }): object | void;
[ng]                         ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:89:5 - error TS2304: Cannot find name 'to_excel'.
[ng] 89     to_excel(options?: {
[ng]        ~~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:89:14 - error TS2304: Cannot 
find name 'options'.
[ng] 89     to_excel(options?: {
[ng]                 ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:89:22 - error TS1109: Expression expected.
[ng] 89     to_excel(options?: {
[ng]                         ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:90:20 - error TS2693: 'string' only refers to a type, but is being used as a value here.
[ng] 90         filePath?: string;
[ng]                       ~~~~~~
[ng] Error: 6mnode_modules/danfojs/types/shared/types.d.ts:90:26 - error TS1005: ',' expected.
[ng] 90         filePath?: string;
[ng]                             ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:91:21 - error TS2693: 'string' only refers to a type, but is being used as a value here.
[ng] 91         sheetName?: string;
[ng]                        ~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:91:27 - error TS1005: ',' expected.
[ng] 91         sheetName?: string;
[ng]                              ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:92:7 - error TS1005: ';' expected.
[ng] 92     }): void;
[ng]          ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:92:13 - error TS1109: Expression expected.
[ng] 92     }): void;
[ng]                ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:93:12 - error TS1005: ';' expected.
[ng] 93     print(): void;
[ng]               ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:93:18 - error TS1109: Expression expected.
[ng] 93     print(): void;
[ng]                     ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:94:1 - error TS1128: Declaration or statement expected.
[ng] 94 }
[ng]    ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:201:5 - error TS1131: Property or signature expected.
[ng] 201     get dtype(): string;
[ng]         ~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:201:5 - error TS2304: Cannot 
find name 'get'.
[ng] 201     get dtype(): string;
[ng]         ~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:201:9 - error TS1005: ';' expected.
[ng] 201     get dtype(): string;
[ng]             ~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:201:9 - error TS2304: Cannot 
find name 'dtype'.
[ng] 201     get dtype(): string;
[ng]             ~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:201:16 - error TS1005: ';' expected.
[ng] 201     get dtype(): string;
[ng]                    ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:201:18 - error TS2693: 'string' only refers to a type, but is being used as a value here.
[ng] 201     get dtype(): string;
[ng]                      ~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:202:5 - error TS2304: Cannot 
find name 'drop_duplicates'.
[ng] 202     drop_duplicates(options?: {
[ng]         ~~~~~~~~~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:202:21 - error TS2304: Cannot find name 'options'.
[ng] 202     drop_duplicates(options?: {
[ng]                         ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:202:29 - error TS1109: Expression expected.
[ng] 202     drop_duplicates(options?: {
[ng]                                 ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:203:16 - error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
[ng] 203         keep?: "first" | "last";
[ng]                    ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:203:26 - error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or 
an enum type.
[ng] 203         keep?: "first" | "last";
[ng]                              ~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:203:32 - error TS1005: ',' expected.
[ng] 203         keep?: "first" | "last";
[ng]                                    ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:204:19 - error TS2693: 'boolean' only refers to a type, but is being used as a value here.
[ng] 204         inplace?: boolean;
[ng]                       ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:204:26 - error TS1005: ',' expected.
[ng] 204         inplace?: boolean;
[ng]                              ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:205:7 - error TS1005: ';' expected.
[ng] 205     }): Series | void;
[ng]           ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:205:9 - error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
[ng] 205     }): Series | void;
[ng]             ~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:205:18 - error TS2532: Object is possibly 'undefined'.
[ng] 205     }): Series | void;
[ng]                      ~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:205:22 - error TS1109: Expression expected.
[ng] 205     }): Series | void;
[ng]                          ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:206:5 - error TS2304: Cannot 
find name 'astype'.
[ng] 206     astype(dtype: "float32" | "int32" | "string" | "boolean", options?: {    
[ng]         ~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:206:12 - error TS2304: Cannot find name 'dtype'.
[ng] 206     astype(dtype: "float32" | "int32" | "string" | "boolean", options?: {    
[ng]                ~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:206:17 - error TS1005: ',' expected.
[ng] 206     astype(dtype: "float32" | "int32" | "string" | "boolean", options?: {    
[ng]                     ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:206:19 - error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
[ng] 206     astype(dtype: "float32" | "int32" | "string" | "boolean", options?: {    
[ng]                       ~~~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:206:31 - error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or 
an enum type.
[ng] 206     astype(dtype: "float32" | "int32" | "string" | "boolean", options?: {
[ng]                                   ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:206:41 - error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or 
an enum type.
[ng] 206     astype(dtype: "float32" | "int32" | "string" | "boolean", options?: {
[ng]                                             ~~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:206:52 - error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or 
an enum type.
[ng] 206     astype(dtype: "float32" | "int32" | "string" | "boolean", options?: {
[ng]                                                        ~~~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:206:63 - error TS2304: Cannot find name 'options'.
[ng] 206     astype(dtype: "float32" | "int32" | "string" | "boolean", options?: {    
[ng]                                                                   ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:206:71 - error TS1109: Expression expected.
[ng] 206     astype(dtype: "float32" | "int32" | "string" | "boolean", options?: {    
[ng]                                                                           ~      
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:207:19 - error TS2693: 'boolean' only refers to a type, but is being used as a value here.
[ng] 207         inplace?: boolean;
[ng]                       ~~~~~~~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:207:26 - error TS1005: ',' expected.
[ng] 207         inplace?: boolean;
[ng]                              ~
[ng] Error: node_modules/danfojs/types/shared/types.d.ts:208:7 - error TS1005: ';' expected.
[ng] 208     }): Series | void;

Solution

  • Tested on MacOS and Windows 10

    Try the following steps to install and use danfojs combined with angular:

    1. Create new angular app with ng new danfojs-app
    2. cd danfojs-app
    3. npm install danfojs
    4. npm install jquery <-- Optional. The demo runs without it too.
    5. Add "scripts": ["./node_modules/jquery/dist/jquery.min.js"] to angular.json <-- Optional.

    angular.json

    {
      "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
      "version": 1,
      "newProjectRoot": "projects",
      "projects": {
        "danfojs-app": {
          "projectType": "application",
          "schematics": {
            "@schematics/angular:application": {
              "strict": true
            }
          },
          "root": "",
          "sourceRoot": "src",
          "prefix": "app",
          "architect": {
            "build": {
              "builder": "@angular-devkit/build-angular:browser",
              "options": {
                "outputPath": "dist/danfojs-app",
                "index": "src/index.html",
                "main": "src/main.ts",
                "polyfills": "src/polyfills.ts",
                "tsConfig": "tsconfig.app.json",
                "assets": [
                  "src/favicon.ico",
                  "src/assets"
                ],
                "styles": [
                  "src/styles.css"
                ],
                "scripts": ["./node_modules/jquery/dist/jquery.min.js"] 
              },
              "configurations": {
                "production": {
                  "budgets": [
                    {
                      "type": "initial",
                      "maximumWarning": "500kb",
                      "maximumError": "1mb"
                    },
                    {
                      "type": "anyComponentStyle",
                      "maximumWarning": "2kb",
                      "maximumError": "4kb"
                    }
                  ],
                  "fileReplacements": [
                    {
                      "replace": "src/environments/environment.ts",
                      "with": "src/environments/environment.prod.ts"
                    }
                  ],
                  "outputHashing": "all"
                },
                "development": {
                  "buildOptimizer": false,
                  "optimization": false,
                  "vendorChunk": true,
                  "extractLicenses": false,
                  "sourceMap": true,
                  "namedChunks": true
                }
              },
              "defaultConfiguration": "production"
            },
            "serve": {
              "builder": "@angular-devkit/build-angular:dev-server",
              "configurations": {
                "production": {
                  "browserTarget": "danfojs-app:build:production"
                },
                "development": {
                  "browserTarget": "danfojs-app:build:development"
                }
              },
              "defaultConfiguration": "development"
            },
            "extract-i18n": {
              "builder": "@angular-devkit/build-angular:extract-i18n",
              "options": {
                "browserTarget": "danfojs-app:build"
              }
            },
            "test": {
              "builder": "@angular-devkit/build-angular:karma",
              "options": {
                "main": "src/test.ts",
                "polyfills": "src/polyfills.ts",
                "tsConfig": "tsconfig.spec.json",
                "karmaConfig": "karma.conf.js",
                "assets": [
                  "src/favicon.ico",
                  "src/assets"
                ],
                "styles": [
                  "src/styles.css"
                ],
                "scripts": []
              }
            }
          }
        }
      },
      "defaultProject": "danfojs-app"
    }
    
    
    1. Add "skipLibCheck": true to tsconfig.json, which will prevent Typescript from type-checking all the imported libraries:
    /* To learn more about this file see: https://angular.io/config/tsconfig. */
    {
      "compileOnSave": false,
      "compilerOptions": {
        "baseUrl": "./",
        "outDir": "./dist/out-tsc",
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "noImplicitOverride": true,
        "noPropertyAccessFromIndexSignature": true,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": true,
        "sourceMap": true,
        "declaration": false,
        "downlevelIteration": true,
        "experimentalDecorators": true,
        "moduleResolution": "node",
        "importHelpers": true,
        "target": "es2017",
        "module": "es2020",
        "skipLibCheck": true,
        "lib": [
          "es2020",
          "dom"
        ]
      },
      "angularCompilerOptions": {
        "enableI18nLegacyMessageIdFormat": false,
        "strictInjectionParameters": true,
        "strictInputAccessModifiers": true,
        "strictTemplates": true
      }
    }
    
    1. Make sure app.component.ts looks like this (The jquery part is optional and can be omitted):
    import { Component, OnInit  } from '@angular/core';
    declare var $: any;
    import * as dfd from "danfojs";
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      title = 'A danfojs test';
    
      public ngOnInit()
      {
        $(document).ready(function(){
    
            const df = new dfd.DataFrame(
            { pig: [20, 18, 489, 675, 1776], horse: [4, 25, 281, 600, 1900] },
            { index: [1990, 1997, 2003, 2009, 2014] }
          );
          df.head().print()
          const s = new dfd.Series([1, 3, 2, 6, 10, 34, 40, 51, 90, 75]);
          s.print()
    
        });
      }
    }
    
    1. Make sure app.component.html looks like this:
    <div class="content" role="main">
    <span>{{ title }} app is running!</span>
    </div>
    
    1. Run ng serve

    And then you should get a result like this after navigating to localhost:4200 in your browser:

    enter image description here

    Using Plotly with danfojs

    If you also want to use Plotly to visualize things, then change index.html like this:

    !doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>DanfojsApp</title>
      <base href="/">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <script src="https://cdn.plot.ly/plotly-1.58.4.min.js"></script>
      <link rel="icon" type="image/x-icon" href="favicon.ico">
    </head>
    <body>
      <app-root></app-root>
    </body>
    </html>
    

    Change app.component.html like this:

    <div class="content" role="main">
    <span>{{ title }} app is running!</span>
    <div id="plot_div"></div>
    </div>
    

    and finally change app.component.ts like this:

    import { Component, OnInit  } from '@angular/core';
    declare var $: any;
    import * as dfd from "danfojs";
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      title = 'A danfojs test';
    
      public ngOnInit()
      {
        $(document).ready(function(){
    
            const df = new dfd.DataFrame(
            { pig: [20, 18, 489, 675, 1776], horse: [4, 25, 281, 600, 1900] },
            { index: [1990, 1997, 2003, 2009, 2014] }
          );
          df.head().print()
          const s = new dfd.Series([1, 3, 2, 6, 10, 34, 40, 51, 90, 75]);
          s.print()
          df['plot']("plot_div").line()
        });
      }
    }
    

    Result:

    enter image description here

    Versions on MacOS:

    Angular CLI: 13.0.3
    Node: 16.10.0
    Package Manager: npm 8.1.4
    OS: darwin x64
    Danfojs: 0.3.3
    Plotly: 1.58.4
    

    Versions on Windows 10:

    Angular CLI: 13.0.3
    Node: 16.13.0
    Package Manager: npm 8.1.4
    OS: win32 x64
    Danfojs: 0.3.3
    Plotly: 1.58.4