JavaScript variable reference in DOM Script not working - javascript

I am new to Vite and want just one simple thing -> to reference a variable in my DOM that I declared in the main.js.
important code from main.js:
let getThis = 'Why does this not work';
important code from index.html:
<body>
<p id="test">not working</p>
<script type="module" src="/main.js"></script>
<script type="module">
document.getElementById('test').innerHTML = getThis;
</script>
Exmple: https://stackblitz.com/edit/vitejs-vite-urotp2?file=main.js,index.html,counter.js&terminal=dev I searched the Internet for 2 Days now:/
First I had a problem using Bootstrap in combination with Vite. I wanted to trigger a Modal via Javascript like in this example: https://stackblitz.com/edit/github-4akyeo?file=src%2Fjs%2Fmain.js,src%2Findex.html
important code from index.html:
<script>
const myModalAlternative = new bootstrap.Modal('#exampleModal');
myModalAlternative.show();
</script>
important code from main.js:
import * as bootstrap from 'bootstrap';
window.bootstrap = bootstrap;
But I always received Uncaught ReferenceError: bootstrap is not defined(look in the console ). I researched and found out that this is because the bootstrap variable is not linked to the window object but this didnĀ“t fix the issue. So I broke it down and realized this is a more general problem. I assume that it has something to do with the bundling of the files and now the variables aren't readable in the <script>.
Is this even possible or am I missing something here? Is this maybe a normal JavaScript scope issue? Thankful for any help.

Thanks to Arnaud from Vite I have solved the problem.
Here is What he told me:
Variables in ESM modules are scoped to the modules, you can only
access them in other modules by exporting them and using import in the
other module, like you did for the counter. More information here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
If you want to bypass this, you can always set something on window
object to make it global, but that should be used only exceptionally
So I researched JS Modules and fixed both problems mentioned above.
Solving the main problem mentioned in the title
I had to export the variable from a file which is imported to my main.js and then import the variable in my .
code from custom.js:
export let getThis = 'Why does this not work';
important code from index.html:
import { getThis } from './custom.js';
see main problem solved
Fixing 'Uncaught ReferenceError: bootstrap is not defined'
I just had to add type="module" to <script> and bootstrap.Modal('#exampleModal'); is working now.
Keep in mind this works only if you first made bootstrap global like:
import * as bootstrap from 'bootstrap';
window.bootstrap = bootstrap; // <- add to window object to bypass the scope and make it global
see bootstrap problem solved - Stackblitz
I hope this helped someone.

Related

How can I use a function in a bundle.js file using <script> to include the bundle?

I have a Javascript module called out.js
export default function out(str) {
//Some Code
console.log(str);
}
I ran the webpack bundler and created a bundle.js file.
And now I am Importing it to my index.html using a tag.
<!DOCTYPE html>
<html>
<head><script defer src="bundle.js"></script></head>
<body>
<script>
out("Hello")
</script>
</body>
</html>
But when I get the following error on the webpage.
index.html:6 Uncaught ReferenceError: out is not defined
I have tried named exports as well as default exports for the out.js, still I get the same error.
You can find a good explanation and the answer here
With my little knowledge of javascript and webpack, I spent hours looking for an answer. The short answer is you need to define your function globally to use this way. You can make out global by adding this block outside of your function.
window.out = out;

What is the reason of a referenceError when trying to use a function from cdn script tag?

I can't use npm, not familiar with the details, currently trying to learn 'redux'. What can be the problem here?
When executing this code, I'm getting a "Uncaught ReferenceError: createStore is not defined
at ind.js:5"
Below you can see the code snippet that I have a problem with:
function playlist(state=[]){
return state;
}
const store = createStore(playlist);
console.log(store.getState());
And I have this script tag in HTML file's head tag:
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.0/redux.min.js"></script>
And the js file's script tag in body's end:
<script type="text/javascript" src="./ind.js"></script>
Ok, I'm sorry my previous answer was unhelpful! As it says in the redux docs you need to import the createStore function before you can use it. That is easily done in Node.js, but without it you need to use the ES6 module. Although support for it is supposedly growing, I've still had plenty of trouble with it. This should be supported in Chrome and Edge. To get this to work on Firefox below version 60, go to about:config and change dom.moduleScripts.enabled to true.
Change your script tag to this:
<script type="module" src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.0/redux.min.js"></script>
and add this as the first line of your code: import { createStore } from 'redux'

Imported Javascript function not defined when called from html

I'm learning laravel 5.5 and VueJs, my issue is when I export some functions from a js file and import it from a second js file it cannot be called from html body. Example:
A.js
function funA(){
}
export {funA};
B.js
import {funA} from './A.js';
At this point if I use the function funA inside the B.js it works, however if I use it on a html page it says funA is not defined. For example:
<!DOCTYPE html>
<html lang="en">
<body>
<button onClick="funA()"></button>
<script src="{{asset('js/B.js')}}"></script>
</body>
</html>
My webpack configuration is something like this:
mix.scripts('resources/assets/js/libs/materialize.js', 'public/js/libs/materialize.js')
.js('resources/assets/js/A.js', 'public/js/js/A.js')
.js('resources/assets/js/B.js', 'public/js/B.js');
Any help would be appreciated. Thank you in advanced.
I think your HTML expects the funA to be on the global window object. The new JavaScript module system doesn't add anything to the global namespace, to avoid namespace pollution.
If you just want to use is anyways on the button then, doing the below should get you working.
window.funA = funA
You can do this in your B.js. Though, I will not recommend this, as I see that you seem to be using Vue and there are better ways to do it. Let me know if this works, also try sharing your Vue code so that someone can help you do it the right way.

Synchronous require in Webpack

I'm using webpack and I'm using require to pull in some packages. I have two packages: package1.js and package2.js. package1.js simply creates an object with some properties called pkg1. package2 is a javascript file that contains a self executing function that extends package1. E.g.
package2.js:
!function () {
pkg1.prototype.newFunction = function {return "foo"};
}()
I'm trying to require both of these into a new script in the following manner:
require('package1')
require('package2')
When I do this, I get an error:
Uncaught TypeError: pkg1.newFunction is not a function
I think this is because of Javascripts asynchronous loading: require(package2) executes before require('package1'). My evidence for this is that when I do the following I don't get an error:
require('package1')
!function () {
pkg1.prototype.newFunction = function {return "foo"};
}()
However, this is very messy, and I would like to use require. How would I go about making this work?
Edit: Specific Examples
The leaflet-d3 plugin begins with:
(function() {
L.HexbinLayer = L.Class.extend({
...
})()
Hence, at least to my understanding, putting in a require(leaflet-d3-plugin) should cause this script to execute and extend L which is brought in by require('leaflet')
Similarly, d3-hexbin-v0 starts with:
!function(){d3.hexbin=function(){
...
}}()
Again, the way I read this is that this script simply adds a .hexbin method to d3.
Now if I were just writing html, I would just put these different things in various script tags and this just works:
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.hexbin.v0.min.js"></script>
or
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
<script src="static/leaflet-d3.min.js" charset="utf-8"></script>
But since I'm using webpack, I should just be able to require and/or import these libraries after I have installed them with npm or if I just copy the .js in these scripts into some directory and then require them from that location. Unfortunately, this does not seem to work unless I copy the .js in these modules directly into whatever script I am writing. This is what I am trying to avoid.
E.g.
import * as d3 from 'd3'; \\I'm using d3 v4 here.
require('/resources/d3-hexbin.min.js')
results in:
Uncaught TypeError: d3.hexbin is not a function
Webpack loades it synchronously but each file have its own scope.
That's why in your statement
import * as d3 from 'd3'; \\I'm using d3 v4 here.
require('/resources/d3-hexbin.min.js')
your second doesn't find d3 variable.
You can solve it by using ProvidePlugin:
webpack.config.js
plugins: [
new webpack.ProvidePlugin({
d3: 'd3'
}),
... //other plugins
This way d3 will be available throughout the application.
Alternative way to achieve it is to use the following:
import * as d3 from 'd3';
window.d3 = d3;
require('./d3.hexbin.v0.min.js')
Hope it helps you!

Calling XQuery using javascript

I want to call a XQuery function with JavaScript to retrieve data from a XML file. I'm able to call this simple function which doesn't read anything from any file:
<script type="text/javascript"
src="mxqueryjs/mxqueryjs.nocache.js"
></script>
<script type="application/xquery">
module namespace m = "http://www.xqib.org/module";
declare function m:GetNearestLocations($node as node()+) {
let $message := "Hello XQuery!"
return $message
};
</script>
With this JavaScript:
var output = xqib.call(
'http://www.xqib.org/module',
'GetNearestLocations',
center.lat());
The return output is as expected "Hello XQuery!".
Now I want to import a math module so that I can use some of its functions while reading data from a XML file.
Here's what I have but the math module doesn't import and causes XQST0059 error saying that there's no information location to load module with namespace "http://www.w3.org/2005/xpath-functions/math":
<script type="text/javascript"
src="mxqueryjs/mxqueryjs.nocache.js"
></script>
<script type="application/xquery">
module namespace m = "http://www.xqib.org/module";
import module namespace math
= "http://www.w3.org/2005/xpath-functions/math";
declare function m:GetNearestLocations($node as node()+) {
let $message := "Hello XQuery!"
return $message
};
</script>
What's is weird about this is that when I use Stylus Studio X15 Entreprise Suite to test the same function the import is working.
Important: I'm using the same JavaScript call when I import or not the Math module, so maybe my problem comes from there but, I don't know how I could fix this.
If you could also guide me a little on what could I set as parameter to m:GetNearestLocations so that I can pass it Integers or Strings
Thanks a lot.
Now I want to import a math module so that I can use some of its functions while reading data from a XML file.
That sounds reasonable. So your first task will be to find an implementation of the math module for namespace http://www.w3.org/2005/xpath-functions/math that XQiB / MXQuery can process, install it on your server, and point to it from the module import statement, as shown in the module import example on the XQiB web site.
Or alternatively, you may decide that you can work with the math functions in http://www.zorba-xquery.com/zorba/math-functions, which MXQuery (and thus XQiB) appear to support natively. (I see this in the MXQuery documentation but not in the XQiB documentation, so I guess there is the theoretical possibility that XQiB is using an older version of MXQuery -- but it's more likely that the development team just has better things to do with their time than document modules already documented elsewhere.)

Categories

Resources