External .js file in an Angular 8 project - javascript

I'm trying to call a function in a .js file from an Angular component, but I get the error "ERROR ReferenceError: myTest is not defined at TechnologiesComponent.onClick".
I have followed the steps described here, so I have created a file called custom.js in my src folder.
The file contains the following:
function myTest() {
alert('Welcome to custom js');
}
$(function() {
alert('Hello, custom js');
});
I have added the script in the scripts array in my angular.json, like so:
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": ["src/custom.js"]
},
The .ts file where I want to use the .js file looks like this:
import { Component } from '#angular/core';
declare const myTest: any;
#Component({
selector: 'app-technologies',
templateUrl: './technologies.component.html',
styleUrls: ['./technologies.component.css']
})
export class TechnologiesComponent {
onClick() {
myTest();
}
}
A button is added to my template:
Click Me
When the button is pressed, the error "ERROR ReferenceError: myTest is not defined at TechnologiesComponent.onClick" is thrown. Why?

declare your function as a variable (in JS both are same)
custom.js
myTest = function(){
alert('Welcome to custom js');
}
also, verify if the script is getting imported in the final build
you may need to re-build if you are using ng serve

If you want to use code from .js files in .ts files you should use export and import.
Example with your project:
custom.js
export function myTest() {
alert('Welcome to custom js');
}
app.component.ts
import {Component} from '#angular/core';
import * as custom from 'src/custom.js';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
onClick() {
custom.myTest();
}
}
take note of line import * as custom from 'src/custom.js';
It's one of the best ways to import smth from non-ts files.
Structure:

I am using angular 10 and trying to access plane js file and It's not allow to change js file
i.e. can't able to add export in it
add your js files in angular.json
I want to access print() function in angular from myJs.js and which is like
// MyJS.js
function print(a){
cosole.log(a +" Code from JS");
}
app.component.ts
import {Component} from '#angular/core';
// following variable name and function name in js file should be same
declare var print: any;
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
onClick() {
print('Yes');
}
}
and fire ng serve again
( If still not work for you then try to put your js file in assets folder and change the path in angular.json)

Related

Import js script to Angular from URL

i am building an app with angular but found a problem I don't know how to solve.
I need to import a js script and it has to be imported from the internet. (because these are their rules, so that they can do hotfixes)
The problem is, when I import the script into my index.html I can only use it in js files not in the typescript files. How can i use the libary in my ts files?
I can't install it via npm and i also can't download the file and add it to my project folder.
The libary is the airconsole API (https://developers.airconsole.com/#!/api)
Thanks for your help
it's only add in your component declare var AirConsole to use it, a fool Component
import { Component, VERSION } from '#angular/core';
declare var AirConsole //<--this is the "magic"
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular ' + VERSION.major;
airConsole=new AirConsole() //<--now you can use airConsole in your component
}
Update Well, generally we can use a service to mannage the airConsole, this allow us that all components that inject the service can use the functions,variables,...
Disclamer: I don't know about "AirConsole", so I imagine control it like we can control others .js like Cordova)
As we need that Angular know when a function is executed in .js, our service can be like
import { Injectable,NgZone } from '#angular/core';
declare var AirConsole;
#Injectable({
providedIn: 'root',
})
export class AirConsoleService implements OnInit {
airConsole=new AirConsole()
message:Subject=new Subject<any>();
constructor(private ngZone: NgZone) { }
ngOnInit(){
this.airconsole.onMessage = (from, data)=>{
this.ngZone.run(() => {
this.message.next({from:from,data:data})
});
})
}
message(device:any,message:any){
this.ngZone.run(() => {
this.airConsole.message(device,message);
});
}
}
So, e.g. you can subscribe to airConsoleService.message

Problem referencing two JavaScript files within Angular component

I have two Javascript files like below, a parent which defines a method and a child which calls the method from the parent:
parent.js
function HelloWorld() {
alert('HelloWorld');
}
child.js
HelloWorld();
In my Angular component I am referencing the script like so:
import { Component } from '#angular/core';
import 'src/app/parent.js';
import 'src/app/child.js';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'my-dream-app';
}
When I run the application, I receive an error in the console stating:
Uncaught ReferenceError: HelloWorld is not defined
If I call HelloWorld() from within Parent.js it works fine; but it doesn't seem like Angular likes have two separate JS files. When I do this in just a pure HTML file and include both scripts in the this works just fine. What am I missing about my Angular component that would prevent what I am trying to do?
That's because typescript is compiling everything to closed annonymous functions. So your parent.js will be compiled to
(function(module, exports) {
function helloWorld () {
console.log('hello')
}
/***/ }),
And you can't have access to that scope.
But if you do a export function helloWorld() {...} and then import it into child.js like:
child.js
import {helloWorld} from '../path/to/child.js'
helloWorld()
OR
import * as parent from './parent.js';
parent.helloWorld()
then child will have access to that function.

How to Use External Javascript in TypeScript Angular

I want to use jquery and easypiechart js file's functions in typescript.
It doesn't work this way.
How to define these script what i specified in code as typescript ?
index.component.ts
import { Component, OnInit } from '#angular/core';
import * as $ from "../../../../../assets/plugins/jquery/jquery.min.js";
import { easyPieChart } from "../../../../../assets/plugins/easypiechart/jquery.easypiechart.min.js";
// these above 2 js files are defined in angular.json script section
#Component({
selector: 'app-index',
templateUrl: './index.component.html',
styleUrls: ['./index.component.scss']
})
export class IndexComponent implements OnInit {
constructor() {}
ngOnInit() {
//$(function(){
// $('.easypiechart').easyPieChart();
//});
// How to write this above script as typescript ?????????????????????
}
}
From the above question,it looks like jquery.easypiechart.min.js is the one that you need to use in your angular application as external js.
Put the js under assets folder say /assets/js/jquery.easypiechart.min.js
Goto your projects angular.json file and under scripts node of architect node put as an entry in the array.
"scripts": [
"./node_modules/jquery/dist/jquery.min.js",
"./src/assets/js/jquery.easypiechart.min.js" ]
Now you can refer the external js in any of your projects components
declare var $: any;// referencing jQuery library
#Component({
selector: 'app-index',
templateUrl: './index.component.html',
styleUrls: ['./index.component.scss']
})
export class IndexComponent implements OnInit {
constructor() {}
ngOnInit() {
$(document).ready(function () {
//accessing easypiechart.min.js.
$('.easypiechart').easyPieChart();
});
}
}
If you have included them in the scripts or index.html, you don't have to import them to the .TS file again
Use declare instead and it should work
What does 'declare' do in 'export declare class Actions'?
Instead of putting it in asset folder you should use it as node_modules dependency
For easy pie chart run this npm i easy-pie-chart --save & for jquery run npm i jquery
Normally you don't want to use jquery in Angular, because it usually implies to modify directly the DOM, which is a bad practice, but there is the way to do it: https://medium.com/all-is-web/angular-5-using-jquery-plugins-5edf4e642969
If you wanna plot a pie chart or other types of charts, you could use ng2-charts instead, it will allow you to use charts.js with Angular and Typescript.

Can't use javascript File object if ionic native File defined in import.

I want to use javascript file object but can't able to use because ionic native file object already has a same key File
Look at below example:
import { File } from '#ionic-native/file';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage{
constructor(private file: File) { }
test(buf){
let file = new File([buf],'test.txt',{type:'text/plain'})
//above javascript File Object is determined as File of #ionic-native/file
}
}
Answer to my own question:
We can import with alias in typescript look below line to get ride of this.
import { File as ionicFile } from '#ionic-native/file';

How to add JQuery in a DotNet generated Angular project?

I've to do some initialization for my theme after the view has been initialized.
I've implemented AfterViewInit, I've managed to import jquery:
import * as $ from 'jquery';
But now I need to execute this:
ngAfterViewInit() {
$(document).trigger('nifty.ready');
}
And I've trouble, because it seems that at this point, document is not known. I guess I should have another import, but I can't find from where?
My whole app.component.ts:
import { Component, AfterViewInit } from '#angular/core';
import * as $ from 'jquery';
#Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
ngAfterViewInit() {
$(document).trigger('nifty.ready');
}
}
The error I get:
Exception: Call to Node module failed with error: TypeError: Cannot
read property 'document' of undefined at module.exports.module.exports
(E:\My\Clients\AppClientApp\dist\vendor.js:12879:12) at
AppComponent.ngAfterViewInit
EDIT
You can find here the whole web app part.
EDIT2
In fact I've the impression that jquery is not initialized properly at all, once loaded(without error), window.jquery return undefined... any idea why?
You can inject the document in your component.
https://angular.io/docs/ts/latest/api/platform-browser/index/DOCUMENT-let.html
import { Component, AfterViewInit, Inject } from '#angular/core';
import {DOCUMENT} from "#angular/platform-browser";
#Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
constructor(#Inject(DOCUMENT) private document) {
}
}
Instead of importing jquery try this -
declare var jQuery:any;
jQuery(document);
console.log jQuery(document) to be sure
P.S make sure jquery is available on the window scope!
I took a look to your project. Well, I didn't test all the .Net features, but I guess your webpack config misses a plugin provider for jQuery (used to be done by angular-cli).
So you ever done :
npm install jquery --save
Try this :
npm install #types/jquery --save-dev
And then add the jquery plugin provider to your webpack.config.js :
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
Finally import it as follow :
import "jquery";
declare var $: any;

Categories