[javascript] Angular 2: import external js file into component

I'm going to import this d3gauge.js file into one of my angular2 component, memmon.component.ts file.

import '../../../../js/d3gauge.js';
export class MemMonComponent {
    createMemGauge() {
        new drawGauge(this.opt);  //drawGauge() is a function inside d3gauge.js
    }
}

and in the corresponding template file, add

<script src="../../../../js/d3gauge.js"></script>

But it doesn't work, drawGaugecan't be found.

So,

  1. what're correct steps to import an external js file to angular2?
  2. since I'm using webpack, is it possible to do it in webpack? I refer to this question , the webpack solution there doesn't work for me as a result of .ensure can't be resolved.

This question is related to javascript angular webpack

The answer is


You can also try this:

import * as drawGauge from '../../../../js/d3gauge.js';

and just new drawGauge(this.opt); in your ts-code. This solution works in project with angular-cli embedded into laravel on which I currently working on. In my case I try to import poliglot library (btw: very good for translations) from node_modules:

import * as Polyglot from '../../../node_modules/node-polyglot/build/polyglot.min.js';
...
export class Lang 
{
    constructor() {

        this.polyglot = new Polyglot({ locale: 'en' });
        ...
    }
    ...
}

This solution is good because i don't need to COPY any files from node_modules :) .

UPDATE

You can also look on this LIST of ways how to include libs in angular.


The following approach worked in Angular 5 CLI.

For sake of simplicity, I used similar d3gauge.js demo created and provided by oliverbinns - which you may easily find on Github.

So first, I simply created a new folder named externalJS on same level as the assets folder. I then copied the 2 following .js files.

  • d3.v3.min.js
  • d3gauge.js

I then made sure to declare both linked directives in main index.html

<script src="./externalJS/d3.v3.min.js"></script>
<script src="./externalJS/d3gauge.js"></script>

I then added a similar code in a gauge.component.ts component as followed:

import { Component, OnInit } from '@angular/core';

declare var d3gauge:any; <----- !
declare var drawGauge: any; <-----!

@Component({
  selector: 'app-gauge',
  templateUrl: './gauge.component.html'
})

export class GaugeComponent implements OnInit {
   constructor() { }

   ngOnInit() {
      this.createD3Gauge();
   }

   createD3Gauge() { 
      let gauges = []
      document.addEventListener("DOMContentLoaded", function (event) {      
      let opt = {
         gaugeRadius: 160,
         minVal: 0,
         maxVal: 100,
         needleVal: Math.round(30),
         tickSpaceMinVal: 1,
         tickSpaceMajVal: 10,
         divID: "gaugeBox",
         gaugeUnits: "%"
    } 

    gauges[0] = new drawGauge(opt);
    });
 }

}

and finally, I simply added a div in corresponding gauge.component.html

<div id="gaugeBox"></div>

et voilĂ  ! :)

enter image description here


For .js files that expose more than one variable (unlike drawGauge), a better solution would be to set the Typescript compiler to process .js files.

In your tsconfig.json, set allowJs option to true:

"compilerOptions": {
     ...
    "allowJs": true,
     ...
}

Otherwise, you'll have to declare each and every variable in either your component.ts or d.ts.


Here is a simple way i did it in my project.

lets say you need to use clipboard.min.js and for the sake of the example lets say that inside clipboard.min.js there is a function that called test2().

in order to use test2() function you need:

  1. make a reference to the .js file inside you index.html.
  2. import clipboard.min.js to your component.
  3. declare a variable that will use you to call the function.

here are only the relevant parts from my project (see the comments):

index.html:

<!DOCTYPE html>
<html>
<head>
    <title>Angular QuickStart</title>
    <base href="/src/">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">

    <!-- Polyfill(s) for older browsers -->
    <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/systemjs/dist/system.src.js"></script>

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

    <!-- ************ HERE IS THE REFERENCE TO clipboard.min.js -->
    <script src="app/txtzone/clipboard.min.js"></script>
</head>

<body>
    <my-app>Loading AppComponent content here ...</my-app>
</body>
</html>

app.component.ts:

import '../txtzone/clipboard.min.js';
declare var test2: any; // variable as the name of the function inside clipboard.min.js

@Component({
    selector: 'txt-zone',
    templateUrl: 'app/txtzone/Txtzone.component.html',
    styleUrls: ['app/txtzone/TxtZone.css'],
})



export class TxtZoneComponent implements AfterViewInit {

    // call test2
    callTest2()
    {   
        new test2(); // the javascript function will execute
    }

}

Instead of including your js file extension in index.html, you can include it in .angular-cli-json file.

These are the steps I followed to get this working:

  1. First include your external js file in assets/js
  2. In .angular-cli.json - add the file path under scripts: [../app/assets/js/test.js]
  3. In the component where you want to use the functions of the js file.

Declare at the top where you want to import the files as

declare const Test:any;

After this you can access its functions as for example Test.add()


1) First Insert JS file path in an index.html file :

<script src="assets/video.js" type="text/javascript"></script>

2) Import JS file and declare the variable in component.ts :

  • import './../../../assets/video.js';
  • declare var RunPlayer: any;

    NOTE: Variable name should be same as the name of a function in js file

3) Call the js method in the component

ngAfterViewInit(){

    setTimeout(() => {
        new RunPlayer();
    });

}

After wasting a lot of time in finding its solution, I've found one. For your convenience I've used the complete code that you can replace your whole file with.

This is a general answer. Let's say you want to import a file named testjs.js into your angular 2 component. Create testjs.js in your assets folder:

assets > testjs.js

function test(){
    alert('TestingFunction')
}

include testjs.js in your index.html

index.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Project1</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">

  <script src="./assets/testjs.js"></script>

</head>
<body>
  <app-root>Loading...</app-root>
</body>
</html>

In your app.component.ts or in any component.ts file where you want to call this js declare a variable and call the function like below:

app.component.ts

import { Component } from '@angular/core';

declare var test: any;


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'app works!';


  f(){
    new test();
  }
}

Finally in your app.component.html test the function

app.component.html

<h1>
  <button (click)='f()'>Test</button>
</h1>

Let's say you have added a file "xyz.js" under assets/js folder in some Angular project in Visual-Studio, then the easiest way to include that file is to add it to .angular-cli.json

"scripts": [ "assets/js/xyz.js" ],

You should be able to use this JS file's functionality in your component or .ts files.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to angular

error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class error TS1086: An accessor cannot be declared in an ambient context in Angular 9 TS1086: An accessor cannot be declared in ambient context @angular/material/index.d.ts' is not a module Why powershell does not run Angular commands? error: This is probably not a problem with npm. There is likely additional logging output above Angular @ViewChild() error: Expected 2 arguments, but got 1 Schema validation failed with the following errors: Data path ".builders['app-shell']" should have required property 'class' Access blocked by CORS policy: Response to preflight request doesn't pass access control check origin 'http://localhost:4200' has been blocked by CORS policy in Angular7

Examples related to webpack

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0 Support for the experimental syntax 'classProperties' isn't currently enabled npx command not found where is create-react-app webpack config and files? How can I go back/route-back on vue-router? webpack: Module not found: Error: Can't resolve (with relative path) Refused to load the font 'data:font/woff.....'it violates the following Content Security Policy directive: "default-src 'self'". Note that 'font-src' The create-react-app imports restriction outside of src directory How to import image (.svg, .png ) in a React Component How to include css files in Vue 2