Using globally defined script inside the component - javascript

I am using global script declaration inside index.html
<!DOCTYPE html>
<html>
<head>
<script src='https://js.espago.com/espago-1.1.js' type='text/javascript'></script>
...
</head>
<body>
...
</body>
Now I want to use it inside the component.
import * as React from "react";
import * as $ from "jquery";
//how to import Espago?
export default class EspagoPayment extends React.Component<any, any> {
componentDidMount() {
$("#espago_form").submit(function(event){
var espago = new Espago({public_key: 'xxx', custom: true, live: false, api_version: '3'});
espago.create_token({
...
});
});
}
render() {
return (
...
);
}
}
Webpack gives an error on build.
error TS2304: Cannot find name 'Espago'
How to get Espago visible inside the component?
Maybe there is other way to link to online js resource?

You have to tell TypeScript that it's defined somewhere else.
declare var Espago: any;
See https://stackoverflow.com/a/13252853/227299

Related

Unexpected token '<' when trying to load my webcomponent in html

so im trying to create a react webcomponent. I wrap it and on VSCode looks fine, but when I'm trying to load it, it gives me the error: Unexpected token '<' on the line:
ReactDOM.render(<Counter/>, mountPoint);
Does anyone know why and how to fix it? thanks
This is my WebComponent:
import React from 'react';
import * as ReactDOM from 'react-dom';
import Counter from './counter';
class CounterWC extends HTMLElement {
connectedCallback() {
// Create a ShadowDOM
const root = this.attachShadow({ mode: 'open' });
// Create a mount element
const mountPoint = document.createElement('div');
root.appendChild(mountPoint);
// You can directly use shadow root as a mount point
ReactDOM.render(<Counter/>, mountPoint);
}
}
customElements.define('counter-wc', CounterWC)
And this is my html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-9" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>React webcomponent:</h1>
<counter-wc></counter-wc>
<script type="module" src="./counterWC.js"></script>
</body>
</html>
Re: comments
The fact that you name your file *.js doesn't mean it is JavaScript
ReactDOM.render(<Counter/>, mountPoint); is JSX, not JavaScript, it needs to be converted in a Build step to JavaScript.
Or do not use React at all:
class CounterWC extends HTMLElement {
constructor(){
super()
.attachShadow({mode: 'open'})
.append(this.div = document.createElement('div'));
}
connectedCallback() {
this.div.innerHTML = `Am I a counter?`;
}
}
customElements.define('counter-wc', CounterWC);
<counter-wc></counter-wc>

Stencil.js: How to use utils function in index.html

i'm creating a popup stenciljs component.
File structure:
popup-element
src
utils
popup-manager
components
popup-element
popup-element.tsx
index.html
...
Now i try to insert component to DOM from function:
popup-manager.ts
export function createMiniNotification(notificationContent: string, mountTarget: HTMLElement = document.body): HTMLElement {
const notify = document.createElement('popup-element');
notify.setAttribute('content', notificationContent);
mountTarget.appendChild(notify);
}
How can I use this function in index.html (in development mode)?
Update:
You can add exports to src/index.ts and then those will be available at /build/index.esm.js.
// src/index.ts
export const createMiniNotification = (msg: string) => console.log(msg);
<script type="module">
import { createMiniNotification } from '/build/index.esm.js';
createMiniNotification('Hi');
</script>
Original Answer:
I'd suggest you create a wrapping component, e. g. app-root and call your function from there, e. g. in its componentDidLoad lifecycle hook:
import { Component, Host, h } from '#stencil/core';
import { createMiniNotification } from '../utils/popup-manager';
#Component({ tag: 'app-root' })
export class AppRoot {
componentDidLoad() {
createMiniNotification(/* ... */);
}
render() {
return <Host />;
}
}
Then you can just add this wrapper component in your index.html:
<app-root></app-root>

jQuery plugin not accessible in React

I have not been successful in importing the following jQuery plugin into my React app:
http://bililite.com/inc/jquery.parsecss.js
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="http://bililite.com/inc/jquery.parsecss.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
My React component:
import React, { Component } from "react";
class Main extends Component {
constructor(props) {
super(props);
$.parsecss(".mybutton { color: #ff0000; }", function(css) {
var x = 0;
x++;
});
}
}
The jQuery function parsecss is undefined.
Adding it to my index.html using a script tag did not work. Only when adding it as a node module and importing it, did it work. Of course, many jquery plugins are not available using npm, so I had to create my own package. This was actually quite simple. In my node_modules folder I created a folder called parsecss and a sub folder called dist. In dist I placed the jquery plugin. In the parsecss folder I added a package.json file that had the following content:
{
"main": "dist/jquery.parsecss.js",
"name": "parsecss",
"title": "parsecss"
}
You need to add jQuery as I showed in my sample code above in the index.html file:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
And in the React component:
/* global $ */
import React, { Component } from "react";
import parsecss from 'parsecss'
class Main extends Component {
constructor() {
$.parsecss(".mybutton { color: #ff0000; }", function(css) {
var x = 0;
x++;
});
}
}
Note: The comment /* global $ */ fixes a console error that indicates that $ is not defined.

How to create and render a React Component after babelify/transpiling?

I have a hello world react component that is written in JSX, transpiled with babel, and then included in the hello.html template of a Flask app. What I have working is creating and rendering the component before transpiling as such:
const hello = <Hello name="world" />;
ReactDOM.render(hello, document.getElementById('hello'));
How can I do those two steps in a <script> tag in my hello.html template? My goal is to be able to pass that name variable from the template to the component and then render it.
A little more context:
The JSX hello.js looks like this:
import React from 'react';
import ReactDOM from 'react-dom'
import { render } from 'react-dom'
class Hello extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<div>Hello {this.props.name}!!!</div>
)
}
}
//The following works:
//const hello = <Hello name="world" />;
//ReactDOM.render(hello, document.getElementById('hello'));
hello.html looks like this:
<html>
<head>
</head>
<body>
<div>ASDF</div>
<div id="hello"></div>
</body>
{# The following line is a post babelify (transpiled) hello.js #}
<script type="text/javascript" src="{{ url_for('static', filename='js/hello.js') }}"></script>
<script type="text/javascript">
{#
What goes here? The code in the above section does not work.
The transpiled code defines a "var Hello = /*#__PURE__*/ function (_React$Component) { ...".
const hello = Hello(); does not throw an error, but also does not render or pass an argument.
hello.render(); is also something that I have tried, along with arguments for div/id to render in and name.
#}
</script>
</html>
Correction: Calling Hello() does not throw an error if the script is text/babel, in which case the script probably isn't doing anything.
The Flask route looks like this:
#app.route(u'/')
def index():
return render_template(u'hello.html', name="universe")
Two ways you can pass variables from your server application to react component:
Use the html data-variable prop.
Create a global variable. Something like window.variable
Then you should be able to access variable as a props like props.variable in your react-component.
My recommended approach I would take is to use a bundler such as SystemJS (version 2), and you will have something like the following:
<!DOCTYPE html>
<html>
<head>
<script src="node_modules/core-js-bundle/minified.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script type="systemjs-importmap" src="systemjs.imports.json"></script>
<script src="node_modules/systemjs/dist/system.min.js"></script>
<script src="node_modules/systemjs/dist/extras/named-exports.min.js"></script>
<script>
System.import('../.playground/index.js').catch(function (err) { console.error(err); });
</script>
</head>
<body>
<div>ASDF</div>
<div id="hello"></div>
</body>
</html>
And index.js will look something like this
ReactDOM.render(
(< Hello/>),
document.getElementById('app')
);
Then your systemjs-importmap will look like this
{
"imports": {
"react": "../node_modules/react/umd/react.production.min.js",
"react-dom": "../node_modules/react-dom/umd/react-dom.production.min.js",
// ... other named exports you want to add like the Hello component here
}
}

JavaScript ReferenceError: $ is not defined

I have an html file that looks like this:
<!DOCTYPE html>
<html>
<head>
<title>AppName</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
</head>
<body>
<div id="container"></div>
<script src="/bundle.js"></script>
</body>
</html>
And I have a javascript file that contains this:
EDIT: included jQuery via npm, and it seems to have worked.
export function getData(arg, callback) {
var $ = require('jQuery'); // This line was added via EDIT above.
$.ajax({
type: "GET",
url: "/get_data",
data: {data: arg},
success: callback
});
}
When I go to my page and execute the function, I eventually get this error:
Uncaught ReferenceError: $ is not defined
at Object.getData (http://localhost:1234/static/bundle.js:21665:6)
Based on the questions/answers I've seen on SOF, it seems like the solution was to include the jquery script in my html file.
Any ideas what I might be doing wrong?
EDIT: As per request, here is my react index.js file. The error is coming from within the searchApi.js file:
import React from 'react';
import ReactDOM from 'react-dom';
import SearchBar from './components/SearchBar';
import * as searchApi from './api/searchApi';
class App extends React.Component {
constructor() {
super();
this.getData = this.getData.bind(this);
this.processData = this.processData.bind(this);
}
getData(data) {
searchApi.getData(data, this.processData);
}
processData(payload) {
console.log(payload);
}
render() {
return (
<div>
<SearchBar getData={this.getData}/>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
);

Categories