How to import JavaScript file into angular2 - javascript

I am having trouble figuring out how to import a javascript file into my angular2 project. It is a file that is not a module that is apart of npm and the only instructions I have been able to find is using npm which is not an option here.
I am using angular cli and in my angular-cli.json file I have:
{
"apps": [
"styles": [..],
"scripts": ["../pathtomyjs/file.js"]
]}
I ran ng build and ng serve and when I open up my app and look at the web console and try referencing the function that is in my js file, I am able to do so successfully.
Example in the console I type in:
var test = MyObject;
and I get test = {};
However, when I try do
let test = MyObject;
in my component .ts file I get :
home.component.ts (10,11): Cannot find name 'MyObject'.)
Not sure how to do this in Angular2.
Thanks!

Do:
declare var MyObject: any;
let test = MyObject;
Or:
let test = (<any> MyObject);
For jQuery:
declare var jQuery: any;
jQuery.ajax({ ... });

Is it a 3rd party library? you'll have to let the typescript compiler know where the type definition files are. Normally, it looks under node_modules/#types folder. For example, if you wanted to use jQuery, you would install the necessary type definition files by running:
npm install #types/jquery

I did a deep dive on this here:
This is a great question and I'm glad you ask because I wish I had what I'm about to write the first time I encountered this little problem. This is a typescript/javascript and webpack issue before it is an angular issue. I definitely am planning a writeup on my blog soon as possible.
Your Scenario:
You run
npm install mathjs
Now you try to use math.js from a component:
Find math.js dist js file (node_modules/mathjs/dist/math.js) and reference like this
import {mathjs} from "../../node_modules/mathjs/dist/math";
But you get error message saying "set --allowJS". You do that like this:
Set --allowJS in config (tsconfig.json)
{ "compilerOptions": {
"allowJs": true, ...
Now you get:
ERROR in ../node_modules/mathjs/dist/math.js (12209,13): Unreachable
code detected.
Looking in the math.js source, you see that it is an old school module but there is no root wrapper function (one function to bring them all and in the darkness bind them..) (more on that later).
Solution: install a typings file for the target lib (#types/mathjs)
read more...

I put my js files into app/assets/scripts and load them in index.html
<script src="assets/scripts/foobar.js"></script> . This is for a ionic2 / angular2 project.
In the module you have to define your functions like this in global scope of the module file
declare var myFancyFunction;

Related

working 'types' definition files, anyone?

We're using Tabulator-tables in a large Angular project and I cannot seem to find a usable definition files.
I've tried https://www.npmjs.com/package/#types/tabulator-tables which seems updated etc but it results in lots of errors in my IDE and the project will not compile as a result. There are many errors even though the compilation worked before I added the types package. Its pointless and impractical to add many #ts-ignore comments.
Be advised - I took notice to use the same version of the type definition package as installed in my project (v4.2.2). I assume the problem is with the automatic generation of the above package - the resulting .d.ts file is not usable as a result.
Please correct me if I'm wrong and any help in integrating definition files will be appreciated. TIA!
I had a similar issue with adding TypeScript typings on Angular project and here's what i did:
encapsulated Tabulator inside Angular component (data-grid.component.ts in my case);
npm install #types/tabulator-tables
created file data-grid.component.d.ts with:
declare module 'tabulator-tables' {
export = Tabulator;
}
the key thing: removed import Tabulator from 'tabulator-tables' from file data-grid.component.ts
And it's worked.
A full set of TypeScript Typings can be found in the #types/tabulator-tables npm package
npm install #types/tabulator-tables
An example of how to use the typings in a project can be found here
The Language Documentation includes more information on the available typings
I already wrote an answer for this issue, not good enough in my opinion, but some people upvoted it as right, so I decided to leave it as it is and write a new one.
There is some issues with adding types for tabulator, this is because type annotations not being exported, but there is a way to use them.
After installation of types for tabulator (npm install --save #types/tabulator-tables), you should open (or create it, if it's not exists) file index.d.ts inside directory src, and copy following code into it:
declare module 'tabulator-tables' {
export = Tabulator;
}
You need to ensure that you have "allowSyntheticDefaultImports": true inside compilerOptions of file tsconfig.json or tsconfig.app.json (depends on your project), and tsconfig.spec.ts (it needs for unit testing).
Very important to unload and start over ng serve after editing of tsconfig.
After that all typings should work. Just in case I created simple Angular example, hope this helps.

Angular testing - test.ts not found

I'm trying to follow the official Angular docs to set up testing for an Angular project - https://angular.io/guide/testing#service-tests
I've downloaded the sample Angular project from the page above, using the first (top) link. I've done an npm install and when I run ng serve it builds fine.
When I run ng test using the CLI, I get the message:
ERROR in Entry module not found: Error: Cant' resolve 'C:Code\testing\src\test.ts' in 'C:\Code\testing'
ERROR in error TS6053: File 'C:Code\testing\src\test.ts' not found.
I looked at this question - How to resolve test.ts when running ng test?, but in that case the file actually exists, but in the Angular example project it doesn't exist at all.
(When I first ran ng test I originally got a message about Jasmine Marbles being missing, which I resolved using:)
npm install jasmine-marbles --save
The documentation says:
You can fine-tune many options by editing the karma.conf.js and the
test.ts files in the src/ folder.
So I know the test.cs is some kind of configuration file, but how do I generate it? It doesn't exist in the Angular 'live example' project either. And how do I know that a test.cs I generate will work reliably with this project?
I used #joshbaeha's suggestion to ng new a new Angular 5 project and copied the test.ts file, which appears to be completely generic and not reliant on project structure or anything else. Everything is now working. Here it is:
test.ts
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone-testing';
import { getTestBed } from '#angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '#angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
I don't know whether you can generate just the test.ts file or not, but as far as i know this file is automatically generated when you create a new angular project using angular-cli. So you can just create a new project using angular-cli then copy the src/test.ts file from that new project

How to include 3rd party library that uses older import approach to Angular4.x?

What is the proper workflow to include the library to angular 4.0 and use it inside a component?
My steps:
yarn add mathjs
Then there should be a way to injects js libraries in one of the build lifecycles so the angular4 component can use it. JHipster utilizes Webpack and Yarn.
Then I tried to add to Component (docs):
import { mathjs } from "./mathjs";
and
var math = require('mathjs');
Those were not working. What am I missing?
UPDATE:
It seems like mathjs uses older approach suggesting var math = require('mathjs'). Maybe it is similar to JQuery question in some way...
UPDATE2
This is a great question and I'm glad you ask because I wish I had what I'm about to write the first time I encountered this little problem. This is a typescript/javascript and webpack issue before it is an angular issue. I definitely am planning a writeup on my blog soon as possible.
Your Scenario:
You run
npm install mathjs
Now you try to use math.js from a component:
Find math.js dist js file (node_modules/mathjs/dist/math.js) and reference like this
import {mathjs} from "../../node_modules/mathjs/dist/math";
But you get error message saying "set --allowJS". You do that like this:
Set --allowJS in config (tsconfig.json)
{ "compilerOptions": {
"allowJs": true, ...
Now you get:
ERROR in ../node_modules/mathjs/dist/math.js (12209,13): Unreachable
code detected.
Looking in the math.js source, you see that it is an old school module but there is no root wrapper function (one function to bring them all and in the darkness bind them..) (more on that later).
Solution: install a typings file for the target lib (#types/mathjs)
First, check to see if you can get #typings files for your module here
https://microsoft.github.io/TypeSearch/
Grab mathjs typings file from npm (https://www.npmjs.com/package/#types/mathjs) and Run npm install to add the typings .d.ts files to the target lib's node_modules directory
npm install --save #types/mathjs
Add your type ref correctly
import * as mjs from "mathjs"
Use it like this:
console.log("e was: " + mjs.e);
I have the complete solution for the math.js lib on my github here
https://github.com/res63661/importOldJSDemoWithTypings/
More:
For examples look no further than your own angular project. CLI creates node_modules folder each time you run npm install after creating a new project with ng new . Dig down into here and note the d.ts files for many of the .js files.
When messing with typings or defining your own (.d.ts files) be sure to restart your server between builds as the typings don't seem to update currently on the fly
Further reading:
http://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html
https://angular.io/guide/typescript-configuration#typescript-typings
https://microsoft.github.io/TypeSearch/
Lastly:
If you are in a pinch and this is not working for you, I did have success creating a custom wrapper for a different (much smaller) module by wrapping it in a master export type
export var moduleNamer = (function(){
//module implementation
}());
then dumping the .js file local to my component and then referencing it as follows:
//reference like this from your component:
import {moduleNamer} from "./source"; //from source.js
--rich
I did this way and it worked for angular9.
First install npm package mathjs.
npm install mathjs
Then import in your component or directive.
import { round } from 'mathjs'
You may test with this.
console.log(round(math.pi, 3) )
Try to include the script into index.html:
<script src="./assets/math.js" type="text/javascript"></script>
Then add this into your component file:
declare const math;
You can then use math in your component:
ngOnInit(): void {
console.log(math.sqrt(-4););
}

How to create aurelia typescript project with vs2017rc

I am new to aurelia, and I need create a prototype project of the framework. At the beginning, I planed to use skeleton-typescript-aspnetcore skeleton, but when I tried the vs2017rc, I found it uses .csproj as the default format(while vs2015 is project.json/.xproj), I think we should follow the vs2017 because we will upgrade our IDE after it's been launched.
The vs2017 have a wizard to upgrade .xproj project, but after the upgrading(skeleton-typescript-aspnetcore), there still lots of error ahead me...
I also tried aurelia-cli, but seems it has not support vs2017 yet, does anyone could give a guide to create the prototype project? I will integrate some plugins like the skeleton mentioned above, such as gulp,karma,breeze...
thank you in advance.
Since Visual Studio 2017 just launched I thought I'd answer how I solved this, as there are still many errors when using "skeleton-typescript-aspnetcore".
Using https://github.com/aurelia/skeleton-navigation/releases/tag/1.1.2 as a starting point, these are the steps to get it running:
When you first run the project you will get errors complaining that some files located in /test/ is not under 'rootDir'. In your tsconfig.json the rootDir is defined as "src/", this can be solved simply by moving your test folder inside your src folder. This will cause new errors because the paths defined in those files has now changed. You will need to edit app, child-router and users imports like this:
import {Users} from '../../users'; IntelliSense should help you out here.
The command gulp test will also not run before changing to the new path, you can change the path in karma.conf.js:
files: [
'src/test/unit/setup.ts',
'src/test/unit/*.ts'
],
Next the file users.ts will throw errors like Type 'Response' is not assignable to type 'any[]'. You will need to tell TypeScript what you're declaring like this: public users : Object = []; or simply: public users = {};
The final problem is that you're going to have a lot of duplicate identifier errors, at the time of writing this the cause of this seems to be from the changes brought on by TypeScript version 2.2.1. I don't know what specifically breaks, but I know that previous version 2.1.5 still works. So what you need to do is to run npm install typescript#2.1.5 --save in your src/skeleton directory, the --save is just to update your package.json file, you can do this on your own later as well if you wish.
After you've done that your gulp errors (20~ of them) should be resolved. But there are still some errors remaining caused by duplicate signatures. Again, things have changed in TypeScript 2.0+, there is now a simplified way of getting and using declaration files. Here is an answer on SO on how to use the #types feature: How should I use #types with TypeScript 2 , but to keep this short and sweet you will have to go to your tsconfig.json file and explicitly tell where to find the #types/node folder. It would look something like this:
"compilerOptions": {
...
"typeRoots": [
"node_modules/#types"
],
"types": [ "node" ]
...
},
Hope this helps, with these changes the project should now build and launch correctly.
EDIT:
I recently ran into some problems again with building my project. I got a lot of duplicate identifiers again... I however ran across this answer on SO: TypeScript throws multiple duplicate identifiers
Apparently TypeScript latest ships with fetch definitions out of the box, so I was able to run the command from the answer in the link:
npm uninstall #types/whatwg-fetch
And upgrading from typescript 2.1.5 to latest:
npm install typescript --save
You might even want to install typescript globally by appending -g.
Also this will continue to be an issue unless you comment out/delete url and whatwg-fetch from typings.json globalDependencies in order to prevent it from recreating itself:
"globalDependencies": {
//"url": "github:aurelia/fetch-client/doc/url.d.ts#bbe0777ef710d889a05759a65fa2c9c3865fc618",
//"whatwg-fetch": "registry:dt/whatwg-fetch#0.0.0+20160524142046"
}
Then you can either delete the typings folder, running typings install again or edit index.d.ts in the typings folder and delete the reference paths to whatwg-fetch and url.
Hope this helps someone who might've encountered the same problems even after "fixing" it.

Local require() paths for React-Native

I am looking for a convenient way to access files in the root of my application while avoiding require() strings that look like:
require('../../../../myModule')
There are some good solutions out there for Node (https://gist.github.com/branneman/8048520) but I haven't seen a way to use global variables in React Native.
Does anyone have a clean solution to this problem?
From Marc Shilling's answer on https://github.com/facebook/react-native/issues/3099
You can use an absolute path on imports/requires:
import {ProximaNovaText} from 'MyApp/src/components';
require('MyApp/src/utils/moment-twitter');
where 'MyApp' is whatever name you registered in your index.ios.js file
Note for VS Code: This works, but be warned that you might lose intellisense and cmd/ctrl + click. Thanks Johan for the info about CS code
You can mark a directory as a package by adding a package.json within the root directory you want to resolve.
e.g:
- app
- package.json // ← Add this package.json file
- config
- components
- ... (etc)
package.json should look like this:
{ "name": "app" }
Restart your packager
react-native start --reset-cache
Now you can use the following in all of you project files:
import store from 'app/config/store';
import Button from 'app/components/Button';
You can use this same method across other directories in your project, I don't think this works via require, although image paths seemed work.
As noted in the comments, you may lose auto-complete in your editor (VSCode).
For Jetbrains IDE's there are some ongoing tickets here:
https://youtrack.jetbrains.com/issue/WEB-17254
https://youtrack.jetbrains.com/issue/WEB-20104#comment=27-1486526
https://intellij-support.jetbrains.com/hc/en-us/community/posts/205434510-Configure-custom-modules-resolve-folder
This might help with Jetbrains IDE's in the meantime.
// A slash may allow auto-complete to work in your IDE (but will fail to resolve)
import Button from '/app/components/Button'; // Cannot be resolved
Put code below on top of your myModule file:
/**
* #providesModule myModule
*/
Then you can use require('myModule') in any other files.
Complementing #Tiagojdferreira
You can use his solution with babel-plugin-module-resolver library.
Install with:
npm install --save-dev babel-plugin-module-resolver
Configure .babelrc adding plugins property like this:
{
"presets": ["react-native"],
"plugins": [
["module-resolver", {
"alias": {
"#src": "MyApp/src",
"#otherAlias": "MyApp/src/other/path",
}
}]
]
}
Usage:
require('#src/utils/moment-twitter');
Hope this helps!
You can use global variables in react native, same as node, properties defined on global are accessible globally.
e.g.
global.foo = "blah";
console.log(foo); //logs "blah"
Most of the node solutions in the gist above should work correctly.
One I've used in the past is defining a global function at the top directory level, usually on the first line like
global.rootRequire = function(path) { return require(path); }
Which simply allows deeply nested requires to be from the root, and avoids all of the ../../ business.
However the other comment is true, if this is really an issue, there is probably something structurally deficient with the project.

Categories

Resources