Localhost not loading module - javascript

I am using modern Javascript MyClass.js
export default class MyClass {
constructor(x) {
this.val=x? x: "Hello!"
console.log("MyClass:",x)
}
}
at my http://localhost/myfolder/mypage.htm, with the source below,
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel='shortcut icon' type='image/x-icon' href='./favicon.ico' />
<script type="module" src="./MyClass.js"></script>
<script>
'use strict';
document.addEventListener('DOMContentLoaded', function(){
alert(123)
let x = new MyClass(11);
}, false); //ONLOAD
</script>
</head>
<body> <p>Hello1!</p> </body>
</html>
Why console say "Uncaught ReferenceError: MyClass is not defined"?
PS: this question is a complement for this other about using ES6+ with browser+NodeJs.
NOTE: using UBUNTU ith Apache's Localhost... Some problem with myfolder a symbolic link to real folder? at /var/www/html I used ln -s /home/user/myRealFolder/site myfolder

you need to import the module before using it
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta charset="utf-8" />
<script type="module" src="./MyClass.js"></script>
<script type="module" id="m1">
// script module is an "island", not need onload.
'use strict';
import MyClass from './MyClass.js';
let x = new MyClass(11); // we can use here...
console.log("debug m1:", x) // working fine!
window.MyClassRef = MyClass; // "globalizing" class
window.xRef = x // "globalizing" instance
</script>
<script> // NON-module global script
document.addEventListener('DOMContentLoaded',function(){
// only works after all modules loaded:
console.log("debug:", window.xRef) // working fine!
let x = new window.MyClassRef(22); // using class also here,
console.log("debug:", x) // working fine!
}, false); //ONLOAD
</script>
</head>
<body> <p>Hello1!</p> </body>
</html>
There are two ways to use an imported class:
at module scope (script m1): you can use new MyClass(), and can "globalize" instances (e.g. xRef) or the costructor's class (MyClassRef).
at global scope: to work together other libraries or with main script, use a global reference, e.g. new window.MyClassRef().
All this solution relies upon "static import"...
Optional dynamic import
You can use also import with ordinary default <script> (no type="module"), and no "onload", using this solution, instead the last script:
<script>
'use strict';
import('./MyClass.js').then(({default: MyClass}) => {
alert(123) // async block
let x = new MyClass(11);
});
</script>
See dynamic import.

Related

Access to javascript module Class/object from index.html

I defined Class in my javascript file...I imported that file into html page:
<script type="module" src="./js/controller.js"></script>
How can I now acces to classes inside of that js file?
I want to have something like this (in my html file):
<script>
let app = null;
document.addEventListener('DOMContentLoaded', function () {
//Init app on DOM load
app = new MyApp();
});
</script>
But it doesn't work (I get Uncaught ReferenceError: MyApp is not defined)...If I include this DOMContentLoaded listener into end of my controller.js file, It works. But I lost reference to app variable this way (which I don't want)... Is there way to have reference to something defined in modules?
Most important reason why I want to have that reference is ability to access to my app object from google chrome console...
Thanks!
You can access your class in js file from html in the following way-
My Home.html file:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<script type="module">
import { Car } from "./main.js";
let obj= null;
alert("Working! ");
obj = new Car("Mini", 2001);
obj.PrintDetails();
document.addEventListener('DOMContentLoaded', function () {
let obj2 = new Car("Merc", 2010);
obj2.PrintDetails();
});
</script>
</head>
<body>
<h1> Lets try something <br></h1>
</body>
</html>
My main.js file:
export class Car {
constructor(name, year) {
this.name = name;
this.year = year;
}
PrintDetails() {
console.log(" Name = "+ this.name);
console.log(" year = "+ this.year);
}
}

Why doesn't Aframe's dependencies attribute not working?

I have the following simple example of initializing entities with components:
<!DOCTYPE html>
<html>
<head>
<title>Hello, WebVR! - A-Frame</title>
<meta name="description" content="Hello, WebVR! - A-Frame">
<script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script>
</head>
<script>
AFRAME.registerComponent('a', {
dependencies: ['b']
});
// Initializes second.
AFRAME.registerComponent('b', {
dependencies: ['c']
});
// Initializes first.
AFRAME.registerComponent('c', {});
</script>
<body>
<a-scene>
</a-scene>
</body>
<script>
sceneEl = document.querySelector('a-scene');
aEntity = document.createElement('a-entity');
aEntity.setAttribute('a');
sceneEl.appendChild(aEntity);
</script>
</html>
This is from the documentation of Aframe regarding components and dependencies
dependencies: allows for control on ordering of component initialization if a component depends on one or more other components. Component names specified in the dependencies array will be initialized left-to-right before initializing the current component. If the dependency have other dependency components, those other dependency components will be ordered in the same manner.
My question is why is this code not working. The code generates the a-entity as expected but no component is being attached. I would expect to see a, b, and c Attached to my entity. What am I doing wrong?
Looks like if you don't supply a value for setAttribute it's ignored.
Try aEntity.setAttribute('a', ''); instead.
Console should show: <a-entity c="" b="" a="" position="" rotation="" scale="" visible=""></a-entity>
<!DOCTYPE html>
<html>
<head>
<title>Hello, WebVR! - A-Frame</title>
<meta name="description" content="Hello, WebVR! - A-Frame">
<script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script>
</head>
<script>
AFRAME.registerComponent('a', {
dependencies: ['b']
});
// Initializes second.
AFRAME.registerComponent('b', {
dependencies: ['c']
});
// Initializes first.
AFRAME.registerComponent('c', {});
</script>
<body>
<a-scene>
</a-scene>
</body>
<script>
sceneEl = document.querySelector('a-scene');
aEntity = document.createElement('a-entity');
aEntity.setAttribute('a', '');
sceneEl.appendChild(aEntity);
console.log(aEntity)
</script>
</html>

Page specific javascripts in Play

I'm building a small application in Play and have an 'outer' template which holds all my CSS and JS imports (jQuery and my main.js file). CSS at the top, JS at the bottom with a body tag in between... pretty basic stuff:
<html>
<head>
<title>test</title>
<link rel="stylesheet" href="#routes.Assets.at("stylesheets/foundation.css")">
<link rel="stylesheet" href="#routes.Assets.at("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="#routes.Assets.at("images/favicon.png")">
</head>
<body>
#content
</body>
<script src='#routes.Assets.at("javascripts/jquery-1.9.0.min.js")' type="text/javascript"></script>
<script src='#routes.Assets.at("javascripts/index.js")' type="text/javascript"> </script>
</html>
Which is fine.
However, I have page specific javascript functions that should run based on what the page is. So if I go to localhost:9000/test, I want a particular set of functions to run.
If I go to localhost:9000/chips, I want another set of functions to run.
I can't see a neat way of doing this, really, except checking the current page url in the script and executing functions based on that... but the routes file is already doing stuff based on the current page url - seems strange to have to do something so similar twice.
One solution is to put all my scripts at the top and then execute inline scripts in the HTML... but I hate doing things like that.
You have very nice and clear sample available in the... documentation.
Scroll to the bottom and check section: moreScripts and moreStyles equivalents, you have there ready to use samples.
I use a ViewModel approach to solve this issue.
The default ViewModel:
class DefaultPage(
implicit val request: RequestHeader,
implicit val lang: Lang) {
var title: String = null
val styles = mutable.LinkedHashMap.empty[String, Int]
val scripts = mutable.LinkedHashMap.empty[String, Int]
def title(title: String) {
this.title = title
}
def style(style: String)(implicit priority: Int = 500) {
styles.put(style, priority)
}
def script(script: String)(implicit priority: Int = 500) {
scripts.put(script.toString, priority)
}
def translate(message: String, objects: Any*) = Messages(message, objects: _*)
}
Then I have two template tags:
styles.scala.html
#(styles: scala.collection.mutable.Map[String, Int])
#for(style <- styles.toList.sortBy(_._2)) {
<link rel="stylesheet" href="#routes.Assets.at(style._1)" />
}
scripts.scala.html
#(scripts: scala.collection.mutable.Map[String, Int])
#for(script <- scripts.toList.sortBy(_._2)) {
<script async="true" src="#routes.Assets.at(script._1)"></script>
}
My main template:
main.scala.html
#(page: util.view.models.DefaultPage)(content: Html)
#import tags.scripts
#import tags.styles
#page.style("css/vendor/normalize.min.css")(1)
#page.style("css/vendor/formalize.min.css")(1)
#page.style("css/sprites.min.css")(1)
#page.style("css/main.min.css")(1)
#page.style("css/quirks.min.css")(1000)
#page.script("js/vendor/jquery-1.9.1.min.js")(1)
#page.script("js/vendor/jquery.formalize.min.js")(1)
#page.script("js/plugins.min.js")(1)
#page.script("js/main.min.js")(1)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>#page.title</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width" />
#styles(page.styles)
<script src="#routes.Assets.at("js/vendor/modernizr-2.6.2.min.js")"></script>
</head>
<body class="#page.lang.code #page.lang.language #page.lang.country">
#content
#scripts(page.scripts)
</body>
And a sub template:
#(page: util.view.models.ContactUsPage)
#page.title(page.translate("contact.us.title"))
#page.style("css/contact-us.min.css")
#page.script("js/vendor/jquery.expandable-1.1.4.js")
#page.script("js/contact-us.min.js")
#main(page) {
}
You can pass your javascript which is specific to a page as template parameter link

function accessing between two or more scripts

I have two scripts and I need to use script1 function in script2. Whats the best way to do it and Is there any simplification using prototype to access function in more scripts. I am using jquery.
script1
$(function(){
function process(){
// some code
}
})
script2
$(function(){
// I would like to use the process function here
}
Sample.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
</HEAD>
<script type="text/javascript" charset="utf-8" src="Script1.js" ></script>
<script type="text/javascript" charset="utf-8" src="Script2.js" ></script>
<script>
</script>
<BODY onload='calling();'>
</BODY>
</HTML>
Scrip1.jc
function call(){
alert("Hi i am called from script2");
}
Scrip2.js
function calling(){
call();
}
Hope this help you.
You can use javascript functions as variables. So just reread your question about the same stuff about variables - Unable to access variable
So just do so your function will be available from global scope.
Just move the function declaration outside the ready event handler, that will make it globally available.
Another idea: use objects:
var Ob = {
process: function(callback) {
callback();
}
}
script1
$(function(){
Ob.process(function(){
... // code
});
});
script 2 (do same)
$(function(){
Ob.process(function(){
... //another code
});
});
If you are using same process function (means same body content, make same thing in both script) then
var Ob = {
process: function() {
...//put code
}
}
script1
$(function(){
Ob.process();
});
script 2 (do same)
$(function(){
Ob.process();
});

Phonegap plugin - module.exports

How are objects passed between the plugin's javascript and the javascript of the view? I'm playing around with an example code from the "apache cordova 3 programming" book and i'm stuck...
In my plugin.xml I set the namespace to "mool"
<js-module src="plugin.js" name="moool">
<clobbers target="mool" />
</js-module>
plugin.js
var mol = {
calculateMOL : function() {
return 42;
}
};
var molll = {
calculateMOLLL : function() {
return 42222;
}
};
module.exports = molll;
module.exports = mol;
index.html
<!DOCTYPE html> <html>
<head>
<title>Meaning of Life Demo</title>
<meta http-equiv="Content-type" content="text/html;
charset=utf-8">
<meta name="viewport" content="user-scalable=no,
initial-scale=1, maximum-scale=1, minimum-scale=1,
width=device-width;" />
<script type="text/javascript" charset="utf-8"
src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
function onBodyLoad() {
document.addEventListener("deviceready", onDeviceReady,
false);
};
function onDeviceReady() {
//alert("onDeviceReady");
};
function doMOL() {
var res = mool.calculateMOL();
alert('Meaning of Life = ' + res);
};
function doMOLL() {
var res = mool.calculateMOLLL();
alert('Meaning of Life = ' + res);
};
</script>
</head>
<body onload="onBodyLoad()">
<h1>MoL Demo</h1>
<p>This is a Cordova application that uses my custom
Meaning of Life plugin. </p>
<button onclick="doMOL();">Button1</button>
<button onclick="doMOLL();">Button2</button>
</body>
</html>
But when I run it only the second button works ... can somebody give me an explanation to this?
I already tried exporting both objects at once like:
module.exports = molll, mol;
but it still won't work...
This is a late comment but might benefit someone else. What worked for me was something similar to the following:
Try rewriting the plugin.js functions as follows:
module.exports.calculateMOL = function() { return 42; };
module.exports.calculateMOLLL = function() { return 42222; };
Drop the two export statements at the end (i.e. module.export = mol; and = molll;)
This should allow the two methods to be accessed as shown in the index.html file above.
It seems as if per definition it only assignes one object!
"The clobbers element specifies the JavaScript object assigned to the loaded JavaScript object."
I notice that in an app I had built, the module.exports property is taking an array, like below. That would allow you to put both your items in there(?) (I am just showing one object of the array in this snippet.)
cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [
{
"file": "plugins/org.apache.cordova.dialogs/www/notification.js",
"id": "org.apache.cordova.dialogs.notification",
"merges": [
"navigator.notification"
]
}, etc

Categories