add javascript libary with jquery dependency to angular 9 - javascript

I want to use watermark.js in my angular app to add watermarks to images before uploading them.
from what i remember, what I did should suffice to make this work:
download
npm i --save watermark.js
add to scripts tag in angular.json
"scripts":[
"./node_modules/jquery/dist/jquery.min.js",
"./node_modules/watermark/dist/jquery.watermark.min.js"
],
use it in a Component
declare var watermark: any;
...
watermark(args)
but i get
ERROR ReferenceError: watermark is not defined
I also tried to declare it as a module by creating src/#types/watermark/index.d.ts and including src/#types it in tsconfig->typeRoots.
declare module 'watermark'
and then importing
import * as w from 'watermark';
But with this the build fails because it cannot find the module 'watermark'.
doing the same with jquery works
import * as $ from 'jquery';
...
$(window).ready(console.log('test'))
any ideas?

According to watermark page: https://lelinhtinh.github.io/watermark/
$(function() {
$('.img_awesome').watermark();
});
so in your component get a handle on a dom element with jQuery then:
$(<selector>).watermark();
for this you need to: declare var $:any;

Related

Rails 7 esbuild - how to manage global javascript functions?

My goal is to create global functions that I can use throughout my application. I found this answer but couldn't really apply it. The most basic gist of what I am wanting to do is:
# app/javascript/application.js
// define global function, but don't run it
function removeFlash(){
// do stuff
}
# app/views/.../update.js.slim
|
// do stuff
// use the global function after other code is ran
removeFlash()
I have a rails 7 esbuild created by doing rails new testapp -j esbuild -d postgresql --css bootstrap
I then added a few modules such as jquery and flatpickr via yarn install. My application.js file looks like:
// Entry point for the build script in your package.json
import "#hotwired/turbo-rails"
import "./controllers"
import * as bootstrap from "bootstrap"
import './vendors/jquery'
import {} from 'jquery-ujs'
import flatpickr from "flatpickr"
$(document).ready(function(){
console.log('hooray')
})
Within the application.js file I want to define a number of global functions so I can call them whenever needed throughout other files rather than repeating the same code over and over.
// Entry point for the build script in your package.json
import "#hotwired/turbo-rails"
import "./controllers"
import * as bootstrap from "bootstrap"
import './vendors/jquery'
import {} from 'jquery-ujs'
import flatpickr from "flatpickr"
function addFlash(msg){
// do stuff
}
function removeFlash(){
// do stuff
}
function performTask(){
// do stuff
}
Since my forms are all remote and happen via js, I have multiple files that will need to run that those functions, such as:
# app/views/objects/create.js.slim
- if #obj.errors.any?
...
- else
|
$("#obj-list").append("#{escape_javascript(render 'obj_row', obj: #obj)}");
$(".close-modal").click();
addFlash("Object successfully created.");
removeFlash();
And this would be duplicated for the update as well as other records.
Apart from just adding a javascript: tag to the bottom of the app/views/layouts/application.html.slim file and declaring all the functions there, I don't understand what the best practice is for handling the above situations.
# app/views/layouts/application.html.slim
doctype html
html
head
title TestApp
...
body
= yield
javascript:
function addFlash(msg){
// do stuff
}
...
What is the best way or standard practice to create and use global functions?
A better alternative to the javascript: tag in the views would be to put the function in the window object, like this:
// app/javascript/application.js
window.removeFlash = function() {
// ...
}
Then everywhere you use it, you have to call it as window.removeFlash().

How to import JQuery UI to angular 8 Project

I'm working on angular app in which i want to implement draggable. There were questions about that in the past but nothing works for me. What I tried:
npm install jquery jquery-ui
and then adding following lines to angular.json
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/jquery-ui/jquery-ui.js"
]
and then importing it to my component like
declare let $: any;
or
import $ from 'jquery';
or
import $ from 'jquery';
import 'jqueryui';
but I'm still getting error:
TSLint: unused expression, expected an assignment or function call(no-unused-expression)
when placing this line in ngOnInit:
$('#draggable' as any).draggable;
You should use it like (call a function):
$( "#draggable" ).draggable();
P.S: Don't use jQuery with Angular :)
Consider using drag-and-drop from Angular CDK (developed by Angular team):
https://material.angular.io/cdk/drag-drop/overview

How to import jQuery into a jQuery plugin in Angular 2+ / Webpack / Angular CLI

I'm trying to import a jQuery plugin into a single Angular component. It runs in every other browser, but IE 11 chokes on it:
SCRIPT1002: Syntax error
main.bundle.js (1376,1)
When I click the error, it shows me the line at issue:
eval("Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery__ = __webpack_require__(\"../../../../jquery/dist/jquery.js\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_jquery__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__angular_core__ = __webpack_require__(\"../../../core/esm5/core.js\");\n// require('jquery');\n\n\n\n/*\ndjaodjin-annotate.js...
That's not all of it, but it appears to be to do with importing jQuery, and indeed, when I remove the jQuery import, it runs fine.
The issue may be that I'm importing jQuery into a JavaScript (.js) file, which is a jQuery plugin. Here's a simplified version of it:
import * as jQuery from 'jquery';
(function($) {
'use strict';
function Annotate(el, options) {
this.init();
}
Annotate.prototype = {
init: function() {
console.log('It\'s working.');
},
};
$.fn['annotate'] = function() {
const annotate = new Annotate($(this));
return annotate;
};
})(jQuery);
If I can't import jQuery into a jQuery plugin, how can I use a jQuery plugin? Is there a way around this?
BTW, I'm using jQuery only in one component. The rest of the application is clean of it.
I'd say you don't need to import jQuery in your plugin; your plugin should just assume that jquery has been included and fail if it has not
You can include jquery (first) then your plugin file into your project. Then in your component just declare jquery
declare let $ : any;
and instantiate your plugin like
$('div').annotate();
I actually found that my jQuery plugin had errors in it. It had a couple of lines with ES6 syntax that IE didn't like. But when Webpack compiles it, it turns the whole thing into a string, all on one line. At runtime, it then runs eval() on the string. So you don't get valuable error messages with line numbers. It just gives you the stupid error that I got. But I think #David has a good point. We maybe don't need to import jQuery.

External JavaScript dependencies in Typescript

I have read a few Q/A on here on how to use external libraries in TS. Following a lot of the suggestions, I'm registering BT alert to an element like this:
import * as $ from "jquery";
import * as bootstrap from 'bootstrap';
window["$"] = $;
window["jQuery"] = $;
$("#clientAlert").alert();
and everything work just fine.
Now I need to do the same for JQuery-Ticker
import * as jqueryTicker from "jquery-ticker";
$('.newsticker').ticker();
WebPack build fails with this error:
error TS2339: Property 'ticker' does not exist on type
'JQuery'.
You could cast it to <any> or extend the jquery typing to add your own method.
(<any>$(".newsticker")).ticker();
//Or add your own custom methods (Assuming this is added by yourself as a part of custom plugin)
interface JQuery {
newsticker():void;
}
Or this
($(".newsticker") as any).ticker();
Try this :
($(".newsticker") as any).ticker();

How to import a js library without definition file in typescript file

I want to switch from JavaScript to TypeScript to help with code management as our project gets larger. We utilize, however, lots of libraries as amd Modules, which we do not want to convert to TypeScript.
We still want to import them into TypeScript files, but we also do not want to generate definition files. How can we achieve that?
e.g. The new Typescript file:
/// <reference path="../../../../definetelyTyped/jquery.d.ts" />
/// <reference path="../../../../definetelyTyped/require.d.ts" />
import $ = require('jquery');
import alert = require('lib/errorInfoHandler');
Here, lib/errorInfoHandler is an amd module included in a huge JavaScript library that we do not want to touch.
Using the above code produces the following errors:
Unable to resolve external module ''lib/errorInfoHandler''
Module cannot be aliased to a non-module type.
This should actually produce the following code:
define(["require", "exports", "jquery", "lib/errorInfoHandler"], function(require, exports, $, alert) {
...
}
Is there a way to import a JavaScript library into TypeScript as an amd Module and use it inside the TypeScript file without making a definition file?
A combination of the 2 answers given here worked for me.
//errorInfoHandler.d.ts
declare module "lib/errorInfoHandler" {
var noTypeInfoYet: any; // any var name here really
export = noTypeInfoYet;
}
I'm still new to TypeScript but it looks as if this is just a way to tell TypeScript to leave off by exporting a dummy variable with no type information on it.
EDIT
It has been noted in the comments for this answer that you can achieve the same result by simply declaring:
//errorInfoHandler.d.ts
declare module "*";
See the github comment here.
Either create your own definition file with following content:
declare module "lib/errorInfoHandler" {}
And reference this file where you want to use the import.
Or add the following line to the top of your file:
/// <amd-dependency path="lib/errorInfoHandler">
Note: I do not know if the latter still works, it's how I initially worked with missing AMD dependencies. Please also note that with this approach you will not have IntelliSense for that file.
Create a file in lib called errorInfoHandler.d.ts. There, write:
var noTypeInfoYet: any; // any var name here really
export = noTypeInfoYet;
Now the alert import will succeed and be of type any.
Typically if you just want to need a temporary-faster-solution, that could be done by defining a new index.d.ts in the root of the project folder, then make a module name like described inside package.json file
for example
// somefile.ts
import Foo from '#awesome/my-module'
// index.d.ts on #awesome/my-module
declare module '#awesome/my-module' {
const bind: any;
export default bind;
}
Ran into that that problem in 2020, and found an easy solution:
Create a decs.d.ts file in the root of your TS project.
Place this declaration:
declare module 'lib/errorInfoHandler';
This eliminates the error in my case. I'm using TypeScript 3.9.7

Categories

Resources