I am incorporating the Dynamic Web Twain javascript library into my angular application to allow my end users to scan using a web browser instead of a desktop application.
Upon loading the page, the progress bar immediately pops up. This is not expected behavior, nor does it happen when I use angular 4. I am using angular 5 at work. It also makes no difference which browser I use (IE, Chrome, Firefox).
The version of my Angular is:
> Angular CLI: 1.6.6 Node: 9.4.0 OS: win32 x64 Angular: 5.2.3 ...
> animations, common, compiler, compiler-cli, core, forms ... http,
> language-service, platform-browser ... platform-browser-dynamic,
> router
>
> #angular/cli: 1.6.6 #angular-devkit/build-optimizer: 0.0.42
> #angular-devkit/core: 0.0.29 #angular-devkit/schematics: 0.0.52
> #ngtools/json-schema: 1.1.0 #ngtools/webpack: 1.9.6
> #schematics/angular: 0.1.17 typescript: 2.5.3 webpack: 3.10.0
I have included the javascript library into my newly created Angular project using these commands:
npm install dwt --save
npm install #type/dwt --save
Also note that my webtwain.min.js is added to the scripts within my angular-cli.json:
"scripts": [
"../node_modules/dwt/dist/dynamsoft.webtwain.min.js"
Here is the layout of my project:
Finally, here is my component.ts file and its related html (it doesn't matter how I populate the html, the result is the same):
/// <reference types="dwt" />
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-scan',
template: '<button (click)="acquireImage()">Scan Document</button><div id="dwtcontrolContainer"></div>',
styleUrls: ['./scan.component.css']
})
export class ScanComponent implements OnInit {
constructor() { }
ngOnInit() {
}
acquireImage(): void {
const dwObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer');
dwObject.IfShowIndicator = false;
const bSelected = dwObject.SelectSource();
if (bSelected) {
const onAcquireImageSuccess = () => { dwObject.CloseSource(); };
const onAcquireImageFailure = onAcquireImageSuccess;
dwObject.OpenSource();
dwObject.AcquireImage({}, onAcquireImageSuccess, onAcquireImageFailure);
}
}
}
Finally here is the result:
The 'progressbar' shown with a value of 0% pops up immediately. In angular 4, this does not happen. Any thoughts on what is causing this? I am trying to read up on the changes between 4 and 5, specifically asynchronous and synchronous loading but I am still new to this framework.
Thanks,
Josh
This is Tom from Dynamsoft.
What you posted here is a known issue in v13.3 of the SDK Dynamic Web TWAIN.
Here is the fix
Update CSS (dynamsoft_dwt_html5.css) to add the following
dialog[closed] {
display: none;
}
Update dynamsoft.webtwain.initiate.js to apply the new CSS rule
m.showDialog=function(y){var z=this,v;if(z.open){j.error("showDialog called on open dialog.");return}z.open=i;z.removeAttribute("closed");
m.closeDialog=function(t){var v=this;if(!v.open){j.error("closeDialog called on closed dialog.")}v.open=o;v.removeAttribute("open");v.setAttribute("closed","closed");
y.push('<dialog class="dynamsoft-dwt-dialogProgress" closed="closed" style="top:30%">
Since the code is minimized, it might look different in your own copy of the JS, if you like, you can email our support team (support#dynamsoft.com, if possible, please use your business email address) for the patch. Thanks.
BTW, the patch will be part of v13.4 soon to be released.
Related
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.
First off, I'm a beginner with NuxtJS and front-end development in general, so it might be that I'm missing something - though I do believe I went through all the options before posting here. Apologies in advance if that is not the case.
I've been having trouble using installed modules that I've registered as plugins. For example, take mapbox-sdk.
After installing it with npm install #mapbox/mapbox-sdk, which correctly creates #mapbox/mapbox-sdk in node_modules, I register it in nuxt.config.js:
plugins: [
...
"~/plugins/mapbox-sdk.js",
],
Of course, I also create the mapbox-sdk.js file in plugins/, containing:
import "#mapbox/mapbox-sdk";
Then, in a page (say, myMap.vue), when I try:
var mapboxClient = mapboxSdk({ accessToken: MY_ACCESS_TOKEN });
which is the basic usage example in the documentation, I get:
mapboxSdk is not defined
in the console. This behavior extends to every single module I installed today, but is not the case for modules I had previously installed.
The reason why you're getting the error mapboxSdk is not defined is because there are a few issues with the way you've set up this plugin.
Docs here https://nuxtjs.org/docs/2.x/directory-structure/plugins/, they have some useful diagrams.
There are a couple of ways you can use this package.
Plugin
// ~/plugins/mapbox-sdk.js
import mapboxSdk from '#mapbox/mapbox-sdk'
export default (_ctx, inject) => {
// Exposing the mapboxSdk to your Nuxt app as $mapBox.
inject('mapBox', mapboxSdk)
}
Then in nuxt.config.js, same as you've already done.
plugins: [
...
"~/plugins/mapbox-sdk.js",
],
Then in your component myMap.vue
var mapboxClient = this.$mapBox({ accessToken: MY_ACCESS_TOKEN });
Directly in the component:
If you don't wish to use a plugin, the way that #kissu mentioned above https://stackoverflow.com/a/67421094/12205549 will also work.
Try adding this after the import to let Vue know that this method exists (in the same .vue file) at first
<script>
import mapboxSdk from '#mapbox/mapbox-sdk'
export default {
methods: {
mapboxSdk,
},
mounted() {
console.log('mapbox function >>', mapboxSdk)
},
}
</script>
Do you have it working in a .vue component at first ?
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:
I'm using #angular#9.0.7, #ngneat/spectator#5.3.1 (with Jest), Inputmask#5.0.3 in a project and everything works on application when I run ng serve or even ng build, but it fails when I try to run a test suite for a #Pipe that uses Inputmask:
#Pipe:
import { Pipe, PipeTransform } from '#angular/core';
import Inputmask from 'inputmask';
#Pipe({
name: 'appSomePipe',
})
export class SomePipe implements PipeTransform {
transform(value: string): string {
return Inputmask.format(value, {
jitMasking: true,
mask: '1111-1',
});
}
}
#Spec:
import { createPipeFactory, SpectatorPipe } from '#ngneat/spectator/jest';
import { SomePipe } from './some.pipe';
describe('SomePipe', () => {
let spectator: SpectatorPipe<SomePipe>;
const createPipe = createPipeFactory(SomePipe);
it('test', () => {
spectator = createPipe(`{{ '11111' | appSome }}`);
expect(spectator.element).toHaveText('1111-1');
});
});
When I run ng test, it shows:
ReferenceError: customElements is not defined
2 |
> 3 | import Inputmask from 'inputmask';
PS: This error just appears for Angular 9, in Angular 8 all tests were successfully passed.
A quick search into inputmask repository shows that it uses customElements which is a feature implemented by modern browsers in order to create native web components (without a framework).
When looking at Jest documentation we can see that the default testEnvironment is jsdom, which is an implementation of the DOM that runs without a browser. This library implements custom elements since version 16.2.0 and this version is pretty recent, and is not yet used by jest (the last version of jest uses jsdom v15.1.1).
So you just have to wait for jest to update the jsdom dependency, and then update your project to use the latest version of jest.
Another option: you can use jest-browser which runs Jest in a headless browser based on puppeteer.
Update 05-2020:
Upgrade to (at least) Jest 26.0.0 which uses jsdom 16.2.0 (Source)
jsdom does not support customElements until v16.2.0 as Guerric P wrote.
To get jest running with jsdom v 16 you need to do the following
yarn add jest-environment-jsdom-sixteen
Then in you jest.config.js add this
module.exports = {
testEnvironment: 'jest-environment-jsdom-sixteen',
...
}
this will force jest to use a newer implementation.
and this should solve your problem.
I remember stumbling upon your question and I stumbled upon something else related to ngx-bootstrap with regards to an import not working in Angular 9.
https://valor-software.com/ngx-bootstrap/#/datepicker
Check out the usage section and its warning about Angular 9.
Try doing import InputMask from 'inputmask/somethingMoreSpecificHere'; or `import { somethingSpecificHere } from 'inputmask';
The problem is that you are not injecting the Inputmask dependency into your test.
This is because you are using a javascript import. There are Angular libraries to do this (ngx-mask).
In Angular we use Dependency Injection with IOC, so for this example I'll use an InputMaskService to create the angular dependency.
Pipe
import { Pipe, PipeTransform } from '#angular/core';
import { InputMaskService } from './inputmask.service';
#Pipe({
name: 'appSomePipe',
})
export class SomePipe implements PipeTransform {
constructor(private inputMaskService: InputMaskService){}
transform(value: string): string {
return this.inputMaskService.format(value, {
jitMasking: true,
mask: '1111-1',
});
}
}
Note that I'm injecting the service in the constructor and using that instance in the transform method.
Test
You can create an instance of your pipe passing the service reference
beforeEach(() => {
const inputMaskService = new InputMaskService();
const pipe = new SomePipe(inputMaskService);
});
We have a unique situation where we use typescript, mixing ng1 and 2, but not using any module loader. I was able to bootstrap both ng 1 and ng2, but i cant get any response from downgraded angular 2 component, i put a break point inside the code and saw that the code runs, but the component doesn't show anything.
I don't get any errors, not in compilation phase and not in runtime.
Here's the code:
myapp.js - angular 1 app definition, es2015
(function() {
'use strict';
angular.module('myApp', []);
})();
myapp.ng2.ts - angular 2 app definition, typescript
namespace MyApp {
let NgModule = ng.core.NgModule;
let BrowserModule = ng.platformBrowser.BrowserModule;
let UpgradeAdapter = ng.upgrade.UpgradeAdapter;
#NgModule({
imports: [BrowserModule]
})
export class MyAppNg2 {}
export const upgradeAdapter = new UpgradeAdapter(MyAppNg2);
$(document).ready(function() {
upgradeAdapter.bootstrap(document.body, ['MyApp'], {strictDi: false});
});
}
fullDetails.component.ts - angular 2, typescript
namespace MyApp.Components.Misc {
let Component = ng.core.Component;
#Component({
selector: 'full-details-header',
template: `This is ng2 component`
})
export class FullDetailsHeaderComponent {
}
}
bootstrap.js - angular1, es2015
angular.module('myApp').component('fullDetailsHeader', MyApp.upgradeAdapter.downgradeNg2Component(MyApp.Components.Misc.FullDetailsHeaderComponent));
It's a little hard to say since I think this is for the beta version of Angular, which I haven't done an upgrade process with, but for Angular versions 2+ you also need to declare your component that you want downgraded in the entryComponents array of your main module:
#NgModule({
imports: [BrowserModule],
entryComponents: [FullDetailsHeaderComponent]
})
Assuming this was for the Angular beta, and you don't have much working, I would scrap this and use the latest version of Angular and follow the official guide. There is just too much that is different in the examples I see for creating an ng1/ng2 hybrid app between the beta and release versions of Angular that I don't feel it's worth troubleshooting problems related to the beta upgrade process.
This is still a fairly difficult area to search for questions and examples on, so if you have a question related to the upgrade process for Angular versions 2+ make a new question and ping me.
To get your started, here's a plunkr which shows a working example of downgrading an Angular component and using it in AngularJS. This also uses multiple transclusion in the downgrade process which only works in versions 4.0.0+.