How to add a Javascript library to Angular 4 component? - javascript

I am trying to figure out how to import JavaScript files ONLY to a specific component.
I put the following code directly into my component:
import "../../vendor/datatables/js/jquery.dataTables.min.js";
import "../../vendor/datatables-plugins/dataTables.bootstrap.min.js";
import "../../vendor/datatables-responsive/dataTables.responsive.js";
But it fires an error saying:
Module not found: Error: Can't resolve 'jquery' in...
Which makes me suspect that the files that depend on jQuery cannot find the jQuery library in this scope.
jQuery itself is put in the angular-cli.json file:
"scripts": [
"./vendor/jquery/jquery.min.js"
],
An alternative is to put all of those 3 external JS files into the angular-cli.json file as well, and it will work, showing the expected result from the user perspective.
But I would like to figure out how to avoid setting the JS globally for those that are used only in a few specific components.
Thanks, please advise.

For example, to import jQuery to your component, you should write:
import * as $ from 'jquery';
Which means "Import all and use as "$" from "jQuery"".
If you downloaded the library by yourself, without npm install, you can try the following (but I'm not sure that it will work):
import * as $ from 'path/to/jquery';

Related

Can't make vue-slick-carousel work from CDN

I'm trying to use it in a very small app using the CDN script:
https://unpkg.com/vue-slick-carousel
with no success.
I'm new to vue.js and I'n not sure if I have to import it or anything.
The documentation says I have to import it: Vue-slick-carousel
IT should be like this but I can't make it work:
import VueSlickCarousel from 'vue-slick-carousel'
// optional style for arrows & dots
import 'vue-slick-carousel/dist/vue-slick-carousel-theme.css'
export default {
name: 'MyComponent',
components: { VueSlickCarousel },
}
The test is in this codepen
Am I missing something?
You can't 'import' from a CDN script in the way you've done. You can access the window variable and assign it to the component. By using a CDN, it becomes bound to the window.
So components: { VueSlickCarousel : window['vue-slick-carousel'] } without the import VueSlickCarousel from 'vue-slick-carousel' would solve that portion of your question.
The issue is that, the code referenced in the example is for packaged installs, and not a CDN. If you can install via npm install vue-slick-carousel, or yarn add vue-slick-carousel, then these problems would resolve themselves.
Edit: As mentioned in the comments, the component should be kebab-case in your HTML. <vue-slick-carousel> ... </vue-slick-carousel> instead of <VueSlickCarousel> ... </VueSlickCarousel>
This is in line with the style guide provided in the Vue docs seen here
In most projects, component names should always be PascalCase in single-file components and string templates - but kebab-case in DOM templates.

Angular import external javascript file, getting no exported member and compile errors

I am writing an angular component and got a open source module working with npm install. Now I made some some changes and want to import the javascript file like so
import { ModuleName } from './../../ModuleFolder/ModuleName';
When I place the cursor above the ModuleName inside the bracket, I see the highlighted red error saying Module has not export member 'ModuleName';
In my ts code, I have referenced the Module like so
object: ModuleName; which is also complaining.
I google and the post says using npm install but I don't want to add this module to my node_module list. I am moving the folder out to make my customization.
I also tried the following but it is not working
import './../../ModuleName.bundle.min.js';
I am wondering does the name of the Module needs to be registered somewhere to be able to reference it in my component?
Thanks for any help.
Use 'declare' after the import statements
declare const _moduleName;
For example:
I am using Swiper.js library using cdn. In my angular component, I refer it using a declare keyword.
declare const Swiper;
var mySwiper = new Swiper('.swiper-container', { /* ... */ });
I got external libraries working in Angular by following the following links
https://hackernoon.com/how-to-use-javascript-libraries-in-angular-2-apps-ff274ba601af

TypeScript import class from another project / module?

I am trying to alter the following build task written in Typescript in the following project:
https://github.com/Microsoft/app-store-vsts-extension/blob/master/Tasks/app-store-promote/app-store-promote.ts
I need an import like the one shown below (or something else that lets me uses the methods in the ios-signing-common module):
import sign = require('ios-signing-common/ios-signing-common');
That import is used in another file in another project:
https://github.com/Microsoft/vsts-tasks/blob/master/Tasks/XamariniOS/xamarinios.ts, however that project is also the same as the ios-signing-common exists in.
https://github.com/Microsoft/vsts-tasks/blob/master/Tasks/Common/ios-signing-common/ios-signing-common.ts
So is it possible to import the ios-signing-common module into the app-store-promote file?
I have tried adding the github path "Microsoft/vsts-tasks" as dependency in package.json, and it downloads it to node_modules, but I still can't resolve the ios-signing-common module.
I hope that any of you can lead me to a solution. :)
I guess I just needed to read up on how module resolving works.
I solved it by adding vsts-tasks as dependency in package.json:
"dependencies": {
"vsts-task-lib": "^0.9.7",
"vsts-tasks": "Microsoft/vsts-tasks"
},
Then I changed the require path to the following:
import sign = require('Agent.Tasks/Tasks/Common/ios-signing-common/ios-signing-common');
And it works!
EDIT - It could compile, but doesn't seem to work when I run it. It fails in the script because it can't find Agent.Tasks/Tasks/Common/ios-signing-common/ios-signing-common.

Importing an old ES5 module for use in a ReactJS component

I'm trying to use an ES5 module in a new ReactJS application and I'm struggling to understand how to correctly import that module, such that the main function within it can be found and executed.
I'm loading the module;
import 'air-datepicker';
I know I'm doing something wrong here and that it's not as simple as this, for an old library that doesn't have proper exports!
Anyway, then I should be able to manually initialise a date picker using an existing div like this;
$('#myDiv').datepicker();
I've tried multiple variations of the import and require, but I'm always getting the same error - 'datepicker is not a function'.
The library I'm experimenting with is air-datepicker. I've installed the module using npm without problems and I know the library works perfectly without React on a simple page loading the script manually in a script tag. My ReactJS app is a basic template created using 'create-react-app', from the FB tutorial pages.
If you're using create-react-app, you should be able to import it like
import 'air-datepicker/dist/css/datepicker.min.css';
import 'air-datepicker';
If you added your jQuery using <script> tag in your HTML, you need to add this line before the air-datepicker imports
const $ = window.jQuery;
const jQuery = window.jQuery;
If you added jQuery using npm install, you'll have to add these following lines
import $ from 'jquery';
import jQuery from 'jquery';
window.$ = $;
window.jQuery = jQuery;
//... air-datepicker imports
Make sure to initialize it inside your componentDidMount or somewhere you're sure that the element has been mounted already.
componentDidMount() {
$('#my-element').datepicker();
}
render() {
return <div>
<input
id="my-element"
type='text'
className="datepicker-here"
data-position="right top" />
</div>
}
Well, that's a day of my life that I'm never getting back!
The problem was caused by Babel import ordering. Import statements are hoisted - meaning they are evaluated first, before any other code (i.e. my window. assignments) are executed. This is 'by design' in babel.
The only way to avoid Babel hoisting, from what I can tell, is to avoid 'import' altogether and use require instead.
So, in the following order the global $ will have been set when you come to require air-datepicker. If you try to 'import' air-datepicker it won't work because Babel will evaluate all of your import statements before executing the window. assignment.
import $ from 'jquery';
window.$ = $;
require('air-datepicker');
There are one or two other approaches that also would have worked, but they are all less desirable because they need you to manually configure webpack - i.e. 'ejecting' the create-react-app config and going it alone...
Use the imports-loader;
// only works if you disable no-webpack-loader-syntax
require("imports?$=jquery!air-datepicker");
or, use the ProvidePlugin, making the module available for all modules.
You have to give it an identifier:
import datepicker from 'air-datepicker';

Why can't I import sprintf-js in TypeScript

I have a TypeScript file into which I'm importing third-party libraries.
import * as _ from 'lodash'; // Works great!
import * as moment from 'moment'; // Works great!
import {vsprintf} from 'sprintf-js'; // Compiler error
As my comments explain, the first two imports work great, but the sprintf-js import does not. I get the following compiler error:
Error TS2307: Cannot find module 'sprintf-js'.
Without a doubt, I have sprintf-js inside of my node_modules folder. I'm not very knowledgeable about node modules. I'm guessing that the sprintf-js libarary does something different than lodash or moment and that TypeScript doesn't like it. How can I make this work?
You will need to add a typing definition for sprintf-js. Depending on your setup - if you have TSD installed and setup with your project, it would be a case of running:
tsd query sprintf-js --action save
otherwise, you can have a read here:
http://definitelytyped.org/
or simply download the typing definition and include it in the project root folder:
https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/master/sprintf-js/sprintf-js.d.ts

Categories

Resources