Using Cytoscape JS with JHipster Angular - javascript

I'm trying to use a plain javascript library (cytoscapejs) into my angular application that is generated using jhipster. I installed the library using npm and added the js file to my vendor.ts file. When I tried to use the library in my component, it is not available. When I inspect I see the library in the source under webpack, but that library is not loaded. I followed the instruction in the ReadMe as it is. Am I missing some additional steps?
Steps followed:
npm install cytoscape
added cytoscape.js to vendor.ts
added the following line in my component "declare const cytoscape: any;"
Tested the code.
"cytoscape is not defined"
But If I add cytoscape cdn link directly in my index.html it works. But I want jhipster vendor build to include cytoscapejs.
Is all the javascript libraries added to vendor.ts gets executed/linked?
Any help would be appreciated.

Cytoscape looks like a nice tool, I never used it before so I integrated it from scratch however it could be easier using one of the few Angular wrappers that exist for it.
The final github repository and the detailed instructions below which are similar to the ones from the Leaflet example from JHipster generated project's README.md with one difference about which bundle to import in vendor.ts and it could be the most important part Cytoscape JS can be used also in a Node app (I followed their doc which mentions webpack)
Install cytoscape using npm install --save-exact cytoscape
Install cytoscape types using npm install --save-dev --save-exact #types/cytoscape
Edit app/vendor.ts
/* ESM version of cytoscape for webpack */
import 'cytoscape/dist/cytoscape.esm.js';
Edit app/home/home.component.html to add a container for our graph
<!-- cytoscape container -->
<div id="cy"></div>
Edit app/home/home.scss to style our container with at least width and height
#cy {
width: 400px;
height: 200px;
}
Edit app/home/home.component.ts to define our graph by importing cytoscape module, then initializing it in ngOnInit()
import * as cytoscape from 'cytoscape';
#Component({
selector: 'jhi-home',
templateUrl: './home.component.html',
styleUrls: ['home.scss'],
})
export class HomeComponent implements OnInit, OnDestroy {
account: Account | null = null;
authSubscription?: Subscription;
cy: any;
constructor(private accountService: AccountService, private loginModalService: LoginModalService) {}
ngOnInit(): void {
this.authSubscription = this.accountService.getAuthenticationState().subscribe(account => (this.account = account));
this.cy = cytoscape({
container: document.getElementById('cy'),
elements: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{
data: {
id: 'ab',
source: 'a',
target: 'b'
}
}]
});
}
and here is the result:

Related

How to use JavaScript files in angular

I am trying to call the javascript function into the angular here is the plugin I am using "npm I global payments-3ds" of which I copied javascript files from node_modules and tried to call in my component
Below is the example :
import {
Component,
OnInit
} from '#angular/core';
import {
handleInitiateAuthentication
} from './globalpayments-3ds/types/index';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
name = 'Angular';
ngOnInit(): void {
const status: any = "CHALLENGE_REQUIRED"
const resp = {
challenge: {
encodedChallengeRequest: "abcd",
requestUrl: "url,
},
challengeMandated: "MANDATED",
dsTransactionId: "44444",
id: "444444",
status: status,
};
const windowSize: any = "WINDOWED_600X400";
const displayMode: any = "lightbox";
const challengeWindow = {
windowSize: windowSize,
displayMode: displayMode,
};
handleInitiateAuthentication(resp, challengeWindow)
}
}
I am trying to call the handleInitiateAuthentication() which is giving me the below error
Here is the file structure
from index.d.ts i am calling the handleInitiateAuthentication() function
Here is Stackblitz code for the same
https://stackblitz.com/edit/angular-vodezz?file=src%2Fapp%2Fapp.component.ts
Please help I never used the js function in angular I tried to add in assets not worked
I have tried to create an angular library and add the js files in it and update the package, by converting the file to .tgz but nothing working it showing always the same error,
Why am I doing is I have to update one of the files from node_modules, basically I wanna change files from node modules which is why i copied those files locally
this is also giving error
You have to import directly js file.
// #ts-ignore
import { handleInitiateAuthentication } from './globalpayments-3ds/globalpayments-3ds.esm.js';
For error about module, it's because you have to define type of your module in TypeScript. You can directly use // #ts-ignore.
See this stackblitz : https://stackblitz.com/edit/angular-xz4kmp?file=src%2Fapp%2Fapp.component.ts
You don't need to import a library like that. First of all install the library to your project:
npm i globalpayments-3ds --save
then in your ts file:
import { handleInitiateAuthentication } from 'globalpayments-3ds';
see this stackblitz
The recommended way to make your own modified versions from open source libraries is to fork them and build your own versions.
Also note that you must take into account the license of that NPM package which in the case of https://github.com/globalpayments/globalpayments-js is GPL-v2, so if you will use it for commercial purposes you must follow the agreement. Check this branch: GNU General Public License (v2): can a company use the licensed software for free?.
Taking a look to your Stackblitz code, you may notice that there are several JS versions of the same module in src/app/global-payments-3ds/ folder:
globalpayments-3ds.js (CommonJS, used in Node environments).
globalpayments-3ds.min.js (CommonJS minified).
globalpayments-3ds.js.map (CommonJS minified map file to reference during debugging).
globalpayments-3ds.esm.js (ESM, ECMA Standard Module).
...
To use an external JS Module in an Angular App, as it is JavaScript and not TypeScript, you must tell TypeScript Compiler that you want to allow JS modules by enabling allowJS: true in tsconfig.ts file at the root of the project.
After that you should be be able to import the ESM version (globalpayments-3ds.esm.js) in your Angular App, or if you want to use the CommonJS version, you can also enable esModuleInterop: true in tsconfig.ts to allow importing CommonJS/AMD/UMD JS modules in your project, like globalpayments-3ds.js.

How to use Panzoom javascript in Angular 8+?

I am unable to use Panzoom Javascript library in Angular. I get
ERROR
Error: panzoom is not defined
Here is the stackblitz of what i have done till now .
Here is the working demo of how it should work
Can any one help me troubleshoot ? Thanks
I have followed all the steps mentioned in this post
It seems Panzoom does have typescript definitions Github Issue
here is a working stackblitz
import { Component, AfterViewInit, ElementRef, ViewChild } from '#angular/core';
import panzoom from "panzoom";
#Component({
selector: 'hello',
template: `<img id="scene" #scene src="https://www.probytes.net/wp-content/uploads/2018/01/5-1.png">`,
styles: []
})
export class HelloComponent implements AfterViewInit {
#ViewChild('scene', { static: false }) scene: ElementRef;
ngAfterViewInit() {
// panzoom(document.querySelector('#scene'));
panzoom(this.scene.nativeElement);
}
}
There is an easy way to do this.
Open your angular project in cmd terminal (root of your project, the same foler which contains /src).
Type npm install panzoom --save (that will add panzoom npm package to your angular.json and install it).
In your component add import import * as panzoom from "panzoom" (your project should automaticaly link it with the right file from node_modules.
in ngOnInit or anywhere needed add this line panzoom.default(document.querySelector('#lipsum'));
You should generally incject this PanZoom package in your component constructor after importing it from node_modules but I'm not sure if there is an integration provided by an author.
Definitely check NPM documentation of this plugin for more info

Import svg.js with plugins in Angular

I have difficulties importing svg.js with it's plugins using typescript in an Angular 5 project.
With npm I installed:
svg.js
svg.draggable.js
In ticket.component.ts:
Imported svg.js as Svg type and this way I can draw a rectangle, this code works:
import * as Svg from 'svg.js'
...
export class TicketComponent implements OnInit {
ngOnInit() {
let draw = Svg('ticket-svg').size(1000, 500);
let rect = draw.rect(800, 300).attr({fill: '#fff', stroke: '#000', 'stroke-width': 1});
}
...
}
But I cannot use functions from the svg.draggable plugin, because it's not imported:
rect.draggable()
// TS2339: Property 'draggable' does not exist on type 'Rect'.
I want something like this:
import * as Svg from {'svg.js', 'svg.draggable.js', 'svg.whatever.js'}
In the GitHub example code of svg.draggable.js they just add these two lines in the html and that's all:
<script src="svg.js"></script>
<script src="svg.draggable.js"></script>
In angular with typescript, this is completely different because I need the import in the ticket.component.ts file, not in the html.
So how to import svg.js with multiple plugins from node_modules as Svg type?
Update 1:
I read a recommendation to import the typings for these 3rd party js libraries, so I installed:
"#types/svg.js": "^2.3.1",
"#types/svgjs.draggable": "0.0.30"
Update 2:
Tried to merge the two js file into one file and import the merged version, but for some reason this hacky way does not work either...
Thanks in advance!
Unfortunately svgjs.draggable.js doesn't have a definition type file so you can't import it with the ES6 import/export like svg.js. the definition type file is the file that has the extension d.ts which you can find in the root of the library.
Also in our case svgjs.draggable extends svg.js. So we need to import svgjs.draggable after svg.js. So how to do that?
The solution is to import them both either from index.html or using angular-cli.json. I'll choose the latter one.
First install both libraries:
$ npm i svg.js -s
$ npm i svg.draggable.js -s
Add to angular-cli.json
"scripts": [
...
"../node_modules/svg.js/dist/svg.min.js",
"../node_modules/svg.draggable.js/dist/svg.draggable.min.js"
...
],
Next tell typescript to stop complaining
We'll do this by using the following syntax declare const which tells typescript that the import does really exist but you just can't know it because you didn't find the definition types file.
So in a component I did a small demo.
import { Component, OnInit } from '#angular/core';
declare const SVG:any;
#Component({
selector: 'app-root',
template: `<div id="canvas"></div>`,
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
ngOnInit() {
const draw = SVG('canvas').size(400, 400);
const rect = draw.rect(100, 100);
rect.draggable();
}
Update: Opps...realized your problem was with svg.draggable.js not just svg.js. I'm going to leave this here if anyone else needs this guidance. Sorry for any confusion.
The following worked for my setup (Angular 9, Typescript, SVG.js v3.0).
Install SVG.js
npm install --save #svgdotjs/svg.js
Import into Component
Per the SVG.js Getting Started guide, import SVG into your component.
import { SVG } from '#svgdotjs/svg.js'
Use SVG as wanted
export class MyComponent implements OnInit {
constructor() {}
ngOnInit(): void {
// don't forget to add "#" CSS selector to the name of the DOM element.
const draw = SVG().addTo('#canvas').size(400, 400);
const rect = draw.rect(100, 100, );
}

Trying to use external Javascript library in angular 5

I'm aware there are similar questions but I still can not get it to work..
So I want to use slick.js so I downloaded the files and put it in my assets folder in my angular application
Ive imported the libraries in my
angular.cli.json
"styles": [
"./assets/scripts/slick-1.8.0/slick.css",
"./assets/scripts/slick-1.8.0/slick-theme.css"
],
"scripts": [
//jQuery imports above
"./assets/scripts/slick-1.8.0/slick.min.js"
]
then In my component...
import { Component, OnInit, Injector } from '#angular/core';
import { AppComponentBase } from '#shared/common/app-component-base';
import * as Slick from '../../../../assets/scripts/slick-1.8.0/slick/slick.min.js';
#Component({
selector: 'app-di-type2',
templateUrl: './di-type2.component.html',
styleUrls: ['./di-type2.component.scss']
})
export class DiType2Component extends AppComponentBase implements OnInit {
public constructor(
injector: Injector
) {
super(injector);
}
ngOnInit() {
const slideContainer = document.querySelector('.slider');
slideContainer.slick({
autoplay: true,
autoplaySpeed: 3500,
});
}
}
from what Ive read about importing external javascript libraries into angular application this should work.. Im getting an error in vscode that says [ts] Property 'slick' does not exist on type 'Element'.any
and then in my console im getting
any help would be appreciated!
Thanks!
Install Slick.js using Node and NPM
https://nodejs.org/
npm install slick-carousel --save
https://www.npmjs.com/package/slick-carousel
Once you install this npm, it'll be saved as a dependency in your package.json file.
Then import Slick:
import 'slick-carousel';
someElement.slick();
You can declare the library as a var of type "any" (assuming it has no typing definitions *.d.ts) after your imports in your component if you import the script in your index.html:
declare let <yourlib>: any;

How to use Phoenix Channels / Sockets in an Angular 2 app?

I have a backend built with Elixir / Phoenix and a frontend built with Angular 2 (Typescript, Brunch,io for building, ES6). I now want to use Phoenix Channels. And I'm a bit desperate trying to use the Phoenix Javascript Client in my frontend.
When I install https://www.npmjs.com/package/phoenix-js via npm install phoenix-js and then try to inject it into a service in angular like this:
import { Socket } from "phoenix-js";
I always get the error Cannot find module phoenix-js during compilation.
I'm a bit stuck and every hint on how to get this to work would be greatly appreciated.
Thanks
Edit: I'm going to leave the old answer below - even though it is a bit emberassing. Getting everything to work and using the most recent version of the Phoenix JS Client with Angular 2 was even easier than I thought and I was just terribly confused.
The Phoenix JS client has been extracted as an npm package and can be found here. Install it with npm install --save phoenix. Then load it as additional dependency. In my setup with SystemJS it was just a matter of adding the necessary configuration:
import { join } from 'path';
import { SeedConfig } from './seed.config';
import { InjectableDependency } from './seed.config.interfaces';
export class ProjectConfig extends SeedConfig {
PROJECT_TASKS_DIR = join(process.cwd(), this.TOOLS_DIR, 'tasks', 'project');
constructor() {
super();
// this.APP_TITLE = 'Put name of your app here';
let additional_deps: InjectableDependency[] = [
// {src: 'jquery/dist/jquery.min.js', inject: 'libs'},
// {src: 'lodash/lodash.min.js', inject: 'libs'},
{src: 'phoenix/priv/static/phoenix.js', inject: 'libs'}
];
const seedDependencies = this.NPM_DEPENDENCIES;
this.NPM_DEPENDENCIES = seedDependencies.concat(additional_deps);
}
}
Now we have it in the global scope and just need to use declare var in the Angular 2 service typescript file where we want to use it. Here was where I made a crucial mistake. I tried to access Socket directly and therefor used declare var Socket: any. Which always led to the error Socket is undefined. But this issue got me in the right direction: If you use the transpiled ES5 version (and not ES6) you have to use Phoenix.Socket (because of namespacing I guess).
So this is how my service looks like now:
import { Injectable } from '#angular/core';
declare var Phoenix: any;
#Injectable()
export class PhoenixChannelService {
socket: any;
constructor() {
this.socket = new Phoenix.Socket("ws://localhost:4000/socket", {
logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }),
transport: WebSocket
});
this.socket.connect();
}
}
Now everything works like a charm.
If you don't want to install the client via npm, there is a more basic way: Just get the latest version of the JS Client from GitHub from /priv/static, store it in the folder where you keep your static assets and include it directly in your index.html:
<script src="/path/to/static/js/phoenix.js"></script>
The rest stays the same.
Note: If you want to use it with typescript type definitions, this npm package might be a good starting point - even though it is a bit old.
Old and embarrassing answer: So I think I figured it out. Writing my own definition file wasn't an option. And since all the documented code on how to use the phoenix client is in ES6 I got stuck including the transpiled ES5 version directly in my index.html. But the first clue was this article.
I then found this issue on GitHub which is about extracting the Phoenix Client. Via this I then found this npm package, which is a bit outdated but seems to work. I install it with npm insall --save phoenix-js and then load the dependency in my project. Since my Angular App is based on this seed it goes into my project definition (and make sure to load the Globals version of the phoenix client:
import { join } from 'path';
import { SeedConfig } from './seed.config';
import { InjectableDependency } from './seed.config.interfaces';
export class ProjectConfig extends SeedConfig {
PROJECT_TASKS_DIR = join(process.cwd(), this.TOOLS_DIR, 'tasks', 'project');
constructor() {
super();
// this.APP_TITLE = 'Put name of your app here';
let additional_deps: InjectableDependency[] = [
// {src: 'jquery/dist/jquery.min.js', inject: 'libs'},
// {src: 'lodash/lodash.min.js', inject: 'libs'},
{src: 'phoenix-js/dist/glob/main.js', inject: 'libs'}
];
const seedDependencies = this.NPM_DEPENDENCIES;
this.NPM_DEPENDENCIES = seedDependencies.concat(additional_deps);
}
}
Now I can use it in my angular 2 service:
import { Injectable } from '#angular/core';
declare var Socket: any;
declare var Channel: any;
#Injectable()
export class PhoenixChannelService {
socket: any;
channel: any;
constructor() {
this.socket = new Socket("/socket", {
logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) })
});
this.socket.connect({user_id: "123"});
}
}
Depending on your build process (I use gulp) and other factors you might have to adapt. But I hope this provides some help to other people stuck with this issue.
Edit: This is the official extracted JS client for Phoenix. But I didn't get it to work in my setup, probably because of Typescript.

Categories

Resources