import third party JS library in open source LWC - javascript

After wasting significant amount of time on how to import jQuery,
I got below 2 ways
in HTML with local path or CDN:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
IN JS with local path or CDN:
var script = document.createElement('script');
script.src = 'https://code.jquery.com/jquery-3.4.1.min.js';
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
But unfortunately both of the above methods won't work in LWC and there is no documentation available on how to do the same.
Below approach works fine in my index.html page to import jQuery in my lwc project.
<script src="./resources/js/jquery-3.5.1.min.js"></script>
I also wasted so many hour on how to import CSS in lwc as there is no documentation available on importing third party CSS also but some how I manged to import css by using below code
constructor() {
super();
const styles = document.createElement('link');
styles.href = './resources/css/bootstrap.css';
styles.rel = 'stylesheet';
this.template.appendChild(styles);
}
So I tried some similar approach to import JS and this doesn't give any errors at the console log but the same doesn't work at all, tried in both constructor and connectedCallback but no luck.
connectedCallback() {
const jq = document.createElement('SCRIPT');
jq.src = './resources/js/jquery-3.5.1.min.js';
jq.type = 'text/javascript';
this.template.appendChild(jq);
}
if anyone has any idea about how to import the JS library in open source LWC then please do let me know, would highly appreciate your help.

First thing that we need to do is to add the JQuery JS file in the
Static Resource. The Static Resource should look something like
below:
JQuery Static Resource
Include JQuery in LWC (Lightning Web Component)
In the JS Controller, we first need to import loadScript() method from
lightning/platformResourceLoader module. We can also include loadStyle
method if we want to include an external CSS file.
import { loadScript, loadStyle } from
'lightning/platformResourceLoader';
Import the Static Resource that we created earlier as well. Check
this implementation to include Static Resource in Lightning Web
Component.
Finally, in the renderedCallback method, call loadScript that we
imported earlier and pass a reference to the current template (this)
and the Static Resource. This method returns the Promise. The then()
function will be called if the Promise is resolved. The catch()
function will be executed if there is an error. We are using
renderedCallback as we want to load the Scripts once the component
is loaded and rendered on UI.
Now, to access the JQuery method in Lightning Web Component, there
is some catch. Ideally, there are multiple ways to call JQuery
methods. The most common one is below:
$(".className").hide();
This will hide the element with class=”className”. But in Lightning
Web Component, we must use it like below:
$(this.template.querySelector('.className')).hide();
That is all. We just need to reference the elements using
queryLocator. Then, we can call the JQuery methods.
import { LightningElement } from 'lwc';
import { loadScript, loadStyle } from
'lightning/platformResourceLoader';
import jQuery from '#salesforce/resourceUrl/JQuery';
lwcJquery.js
import { LightningElement } from 'lwc';
import { loadScript, loadStyle } from
'lightning/platformResourceLoader';
import jQuery from '#salesforce/resourceUrl/JQuery';
export default class LwcJquery extends LightningElement {
renderedCallback(){
loadScript(this, jQuery)
.then(() => {
console.log('JQuery loaded.');
})
.catch(error=>{
console.log('Failed to load the JQuery : ' +error);
});
}
slideIt(event){
$(this.template.querySelector('.panel')).slideToggle("slow");
}
slideRight(event){
$(this.template.querySelector('.innerDiv')).animate({left:
'275px'});
}
}
Here, I have used slideToggle() and animate() JQuery methods to add
some animation.

Related

How to use external JavaScript objects in Vue.js methods

I'm trying to get Stripe working with my Vue.js 2 application. For PCI-DSS reasons, Stripe requires that their Javascript is always loaded from js.stripe.com. I've followed the instructions in:
How to add external JS scripts to VueJS Components
How to include a CDN to VueJS CLI without NPM or Webpack?
but I get a 'Stripe' is not defined error when I try to use the library. These solutions seemed to be aimed at merely getting a <script> tag into the output HTML (e.g. for analytics), not actually consuming the functions and objects in that script.
Here's what my component Javascript looks like:
<script>
export default {
name: "PaymentPage",
mounted() {
let stripeScript = document.createElement('script');
stripeScript.setAttribute('src', 'https://js.stripe.com/v3/');
document.head.appendChild(stripeScript);
let s = Stripe('pk_test_Fooo');
console.log(s);
}
}
</script>
I also tried adding the script tag to my public/index.html file instead, but I get the same outcome. This would probably be my preferred route, since Stripe encourages developers to import their script on all pages on the site.
<!DOCTYPE html>
<html lang="en">
<head>
// ...
<script src="https://js.stripe.com/v3/"></script>
</head>
How can I pull a script from an external CDN and use it within my component's Javascript?
I'm aware of some libraries to integrate Vue.js with Stripe (e.g. matfish2/vue-stripe and jofftiquez/vue-stripe-checkout), but the former doesn't import properly for me (I'm hitting issue #24) and the latter is built against the older Stripe API and the new version is still in beta.
You aren't giving the script time to load before checking if Stripe is there. What you need is something like this:
<script>
export default {
name: "PaymentPage",
mounted() {
let stripeScript = document.createElement('script');
stripeScript.setAttribute('src', 'https://js.stripe.com/v3/');
stripeScript.onload = () => {
let s = Stripe('pk_test_Fooo');
console.log(s);
};
document.head.appendChild(stripeScript);
}
}
</script>
Thanks to yuriy636's comment, I realised that errors were only from the linter, which presumably can't statically figure out what I'm up to.
I opted to put the script into index.html, then ensured I squashed linter errors with:
// eslint-disable-next-line no-undef
let s = Stripe('pk_test_Fooo');
In my case, I still had errors calling functions of the specific script. So it was required to specify the ¨window¨ scope. Also, if you need to access any Vue element inside the ¨onload¨function, you need a new variable for the ¨this¨ instance.
<script>
export default {
name: "PaymentPage",
mounted() {
let stripeScript = document.createElement('script');
// new variable for Vue elements.
let self = this;
stripeScript.onload = () => {
// call a script function using 'window' scope.
window.Stripe('pk_test_Fooo');
// call other Vue elements
self.otherVueMethod();
};
stripeScript.setAttribute('src', 'https://js.stripe.com/v3/');
document.head.appendChild(stripeScript);
}
}
I worked with this on Vue 2.6.
Just install the npm package npm install #stripe/stripe-js and use it like a regular import
import { loadStripe } from "#stripe/stripe-js";
export default {
async mounted() {
// init stripe
const stripe = await loadStripe('your_stripe_key_here');
this.stripe = stripe; // store the stripe instance
// access the stripe instance in your methods or where you want to use them
},
}
It's working as of 6th Jan 2022.

How to use an external non vue script in vue

I try to use an external script (https://libs.crefopay.de/3.0/secure-fields.js) which is not vue based
I added the script via -tags into index.html
But when I try to intsanciate an object, like in the excample of the script publisher.
let secureFieldsClientInstance =
new SecureFieldsClient('xxxxx',
this.custNo,
this.paymentRegisteredCallback,
this.initializationCompleteCallback,
configuration)
Vue says "'SecureFieldsClient' is not defined"
If I use this.
let secureFieldsClientInstance =
new this.SecureFieldsClient('xxxxx',
this.custNo,
this.paymentRegisteredCallback,
this.initializationCompleteCallback,
configuration)
secureFieldsClientInstance.registerPayment()
Vue says: Error in v-on handler: "TypeError: this.SecureFieldsClient is not a constructor"
My Code:
methods: {
startPayment () {
this.state = null
if (!this.selected) {
this.state = false
this.msg = 'Bitte Zahlungsweise auswählen.'
} else {
localStorage.payment = this.selected
let configuration = {
url: 'https://sandbox.crefopay.de/secureFields/',
placeholders: {
}
}
let secureFieldsClientInstance =
new SecureFieldsClient('xxxxx',
this.custNo,
this.paymentRegisteredCallback,
this.initializationCompleteCallback,
configuration)
secureFieldsClientInstance.registerPayment()
// this.$router.replace({ name: 'payment' })
}
}
}
Where is my mistake?
EDIT:
Updated the hole question
Here is a minimal Vue app for the context your provided, which works:
https://codepen.io/krukid/pen/voxqPj
Without additional details it's hard to say what your specific problem is, but most probably the library gets loaded after your method executes, so window.SecureFieldsClient is expectedly not yet defined. Or, there is some runtime error that crashes your script and prevents your method from executing. There could be some other more exotic issues, but lacking a broader context I can only speculate.
To ensure your library loads before running any code from it, you should attach an onload listener to your external script:
mounted () {
let crefPayApi = document.createElement('script')
crefPayApi.onload = () => this.startPayment()
crefPayApi.setAttribute('src', 'https://libs.crefopay.de/3.0/secure-fields.js')
document.head.appendChild(crefPayApi)
},
I found the solution.
the import was never the problem.
I had just to ignore VUEs/eslints complaining about the missing "this" via // eslint-disable-next-line and it works.
So external fuctions/opbjects should be called without "this" it seems.
let secureFieldsClientInstance =
new SecureFieldsClient('xxxxx',
this.custNo,
this.paymentRegisteredCallback,
this.initializationCompleteCallback,
configuration)
You could download the script and then use the import directive to load the script via webpack. You probably have something like import Vue from 'vue'; in your project. This just imports vue from your node modules.
It's the exact same thing for other external scripts, just use a relative path. When using Vue-CLI, you can do import i18n from './i18n';, where the src folder would contain a i18n.js
If you really want to use a CDN, you can add it like you normally would and then add it to the externals: https://webpack.js.org/configuration/externals/#externals to make it accessible from within webpack

How to use methods from external js in Angular

I need to call a function from external js file into my Angular component
I already go through the related question
How can i import external js file in Angular 5?
How to include external js file in Angular 4 and call function from angular to js
My External JS (external.js)
var radius = 25;
function calculateRadius(pi) {
let piValue = 3.14159;
if(pi) {
piValue = pi;
}
var result = piValue * radius * radius;
console.log('Result: ', result);
}
function wrapperMethod(pi) {
console.log('Hi, this is from wrapper method');
calculateRadius(pi)
}
I added the said JS file in the angular.json under scripts block
"scripts": [
"src/assets/external.js",
]
In the CircleComponent, I would like to call the method
import wrapperMethod from '../../src/assets/external.js';
#Component({
selector: 'app-circle',
templateUrl: './circle.component.html',
styleUrls: ['./circle.component.css']
})
export class CircleComponent implements OnInit {
constructor() { }
ngOnInit() {
wrapperMethod(3.14159);
}
}
But its failing to call the method. Kindly assist me how to achieve this.
Note: The said methods as just an example methods, I want to implement this logic with the complex code file. The said question tells about typings.d.ts, but I don't know where is typings.d.ts in my Angular project. Kindly brief me regarding this. If the said question gives good solution means, why should I post this question.
Angular Structure (Created using Angular CLI)
I don't know where is typings.d.ts, could anyone please tell me where is typings.d.ts - which is mentioned in the said questions How to include external js file in Angular 4 and call function from angular to js
You can follow this below steps
1) First add a reference of your external JS file for importing it to the component.
import * as wrapperMethods from '../../src/assets/external.js';
2) Now declare a "var" of the same name that your function has inside external JS.
declare var wrapperMethods: any;
3) ngOninit(){
wrapperMethods();
}
put your external .js file under scripts in build
if still can not see methods inside it put in in index.html
<script src="assets/PATH_TO_YOUR_JS_FILE"></script>
in your component after import section
declare var FUNCTION_NAME: any;
ANY_FUNCTION() {
FUNCTION_NAME(params);
}
Don't get confused with typings.d.ts. Follow below steps.
1.Add your external file inside assets folder. The content of this file will be by default included as per your angular-cli.json.
2.The function of your js which you're going to use must be exported. i.e.
export function hello() {
console.log('hi');
}
3.Import your file inside your component as below.
import * as ext from '../assets/some-external.js';
4.Now you can reference it like
ext.hello();
Steps:-
1. create a external js file.
2. In component.ts use the below code.
ngOnInit() {
this.loadJsFile(JsFilePath);
}
public loadJsFile(url) {
let node = document.createElement('script');
node.src = url;
node.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(node);
}
3. If u use jquery then define selector in html to render. Or store data in variable.
Make sure you have to add jquery cdn in index.html and you have to install Jquery and its types package from npm.

Importing javascript file for use within vue component

I am working on a project that requires using a js plugin. Now that we're using vue and we have a component to handle the plugin based logic, I need to import the js plugin file within the vue component in order to initialize the plugin.
Previously, this was handled within the markup as follows:
<script src="//api.myplugincom/widget/mykey.js
"></script>
This is what I tried, but I am getting a compile time error:
MyComponent.vue
import Vue from 'vue';
import * from '//api.myplugincom/widget/mykey.js';
export default {
data: {
My question is, what is the proper way to import this javascript file so I can use it within my vue component?
...
Include an external JavaScript file
Try including your (external) JavaScript into the mounted hook of your Vue component.
<script>
export default {
mounted() {
const plugin = document.createElement("script");
plugin.setAttribute(
"src",
"//api.myplugincom/widget/mykey.js"
);
plugin.async = true;
document.head.appendChild(plugin);
}
};
</script>
Reference: How to include a tag on a Vue component
Import a local JavaScript file
In the case that you would like to import a local JavaScript in your Vue component, you can import it this way:
MyComponent.vue
<script>
import * as mykey from '../assets/js/mykey.js'
export default {
data() {
return {
message: `Hello ${mykey.MY_CONST}!` // Hello Vue.js!
}
}
}
</script>
Suppose your project structure looks like:
src
- assets
- js
- mykey.js
- components
MyComponent.vue
And you can export variables or functions in mykey.js:
export let myVariable = {};
export const MY_CONST = 'Vue.js';
export function myFoo(a, b) {
return a + b;
}
Note: checked with Vue.js version 2.6.10
try to download this script
import * from '{path}/mykey.js'.
or import script
<script src="//api.myplugincom/widget/mykey.js"></script>
in <head>, use global variable in your component.
For scripts you bring in the browser way (i.e., with tags), they generally make some variable available globally.
For these, you don't have to import anything. They'll just be available.
If you are using something like Webstorm (or any of the related JetBrains IDEs), you can add /* global globalValueHere */ to let it know that "hey, this isn't defined in my file, but it exists." It isn't required, but it'll make the "undefined" squiggly lines go away.
For example:
/* global Vue */
is what I use when I am pulling Vue down from a CDN (instead of using it directly).
Beyond that, you just use it as you normally would.
I wanted to embed a script on my component and tried everything mentioned above, but the script contains document.write. Then I found a short article on Medium about using postscribe which was an easy fix and resolved the matter.
npm i postscribe --save
Then I was able to go from there. I disabled the useless escape from eslint and used #gist as the template's single root element id:
import postscribe from 'postscribe';
export default {
name: "MyTemplate",
mounted: function() {
postscribe(
"#gist",
/* eslint-disable-next-line */
`<script src='...'><\/script>`
);
},
The article is here for reference:
https://medium.com/#gaute.meek/how-to-add-a-script-tag-in-a-vue-component-34f57b2fe9bd
For anyone including an external JS file and having trouble accessing the jQuery prototype method(s) inside of the loaded script.
Sample projects I saw in vanilla JS, React and Angular were simply using:
$("#someId").somePlugin(options)
or
window.$("#someId").somePlugin(options)
But when I try either of those in my VueJS component I receive:
Error: _webpack_provided_window_dot$(...).somePluginis not a function
I examined the window object after the resources had loaded I was able to find the jQuery prototype method in the window.self read-only property that returns the window itself:
window.self.$("#someId").somePlugin(options)
Many examples show how to load the external JS file in VueJS but not actually using the jQuery prototype methods within the component.

Google Calendar Api React 'gapi not found'

I am new to google calendar api and react so I'm sure there is something small I'm missing here. I cannot import the necessary google api libraries to call "gapi." I have try to import them like I would do from local libraries but still get the error "gapi is not defined". I need to use the "gapi" in my component so I don't think I can call and append the script to the body using the componentDidLoad.
// Libraries
import React, {Component} from 'react';
//...import other libraries
//import google libraries in order to use "gapi" and call "checkAuth"
import 'https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.min.js';
import 'https://apis.google.com/js/client.js?onload=checkAuth';';
var CLIENT_ID = 'MY_CLIENT_ID_IS_HERE';
var SCOPES = ["https://www.googleapis.com/auth/calendar"];
class NewCalendar extends Component {
constructor(props) {
super(props);
this.checkAuth = this.checkAuth.bind(this);
}
checkAuth() {
console.log('checkAuth running...')
gapi.auth.authorize( //ISSUE
^issue with the last line
{
'client_id': CLIENT_ID,
'scope': SCOPES.join(' '),
'immediate': true
}, this.handleAuthResult);
}
...
}
export default NewCalendar;
Does anyone know how to resolve this issue?
Thanks a million.
I struggled with similiar issues. Thats how I solved it. In this case you Need to put the window. scope infront. But hopfeully you found a solution until now ;) Want to share this anyway, maybe it's not the best solution but works for me for the Moment.
componentDidMount() {
this.loadApi();
}
loadApi() {
const script = document.createElement("script");
script.src = "https://apis.google.com/js/api.js";
document.body.appendChild(script);
script.onload = () => {
window.gapi.load('client:auth2', this.checkAuth.bind(this));
}
}
bye
I am pretty new to React and JSX but it seems that you might have ideas to answer your problems here:
GAPI is not defined - ReactJS - Google Sheets
https://github.com/anthonyjgrove/react-google-login/blob/master/src/index.js#L33
It seems that import only works for local files, and that you will need to to async load of the gapi (https://jsx.github.io/doc/importref.html)
Hope that helps
Place your https://apis.google.com/js/api.js inside a script tag inside of your index.html file, below your meta tag. That should be it.
Then in the browser, refresh the page and in your JavaScript console, you should be able to write out gapi and you should be able to see an object like so: {load: f}.
That object would be the Google API that is available on the window scope of your browser.

Categories

Resources