Required parameter is undefined in RequireJS - javascript

Whenever I try to load a page specific script with RequireJS, it will tell me that Builds is undefined.
<script type="text/javascript">
requirejs(["../../js/builds/builds"], function(Builds) {
console.log(Builds);
Builds.createFunc(window.location.href.substring(window.location.href.lastIndexOf("/") + 1))
});
</script>
js/builds/builds.js
"use strict";
define(["../../classes/builds/builds"], (Builds) => {
const Create = (classID) => {
return new Builds(classID);
}
return {
createFunc: Create
}
});
classes/builds/builds.js
"use strict";
define(() => {
return class Builds {
constructor(arg) {
this.arg = arg;
this.init();
}
init() {
console.log("Build loaded with class ID " + this.arg);
}
}
});
The only time I've got it to work is when I bind Create to window but that's not what I want to do. I want to be able to access the Builds parameter in my page script.
Folder structure:
resources (where the source files are, I'm compiling them with WebPack)
resources/js/app/modules/builds/builds.js compiles into public/js/builds/builds.js
public folder
Config:
requirejs.config({
baseUrl: "js/lib",
paths: {
app: "../app"
}
});
What am I missing here?

I got it working but I put all the files in one scripts folder except for the index.html. Four .js files: require.js, main.js, builds.js and class.js. But I did not use webpack. I was just testing if your code was correct (I have never used requireJS, before).
Index.html:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script data-main="./scripts/main" src="./scripts/require.js"></script>
</body>
</html>
main.js:
console.log(Builds);
Builds.createFunc(window.location.href.substring(window.location.href.lastIndexOf("/") + 1))
});
builds.js:
"use strict";
define(["./class"], (Builds) => {
const Create = (classID) => {
return new Builds(classID);
}
return {
createFunc: Create
}
});
class.js:
"use strict";
define(() => {
return class Builds {
constructor(arg) {
this.arg = arg;
this.init();
}
init() {
console.log("Build loaded with class ID " + this.arg);
}
}
});

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);
}
}

How can I execute scripts in a React.js component?

I received an HTML file with 2 scripts in the head and I'm figuring out the best way to execute them in my react app. The first script load socket.io.js and the second contains the JS code for the upload system:
Original code
//...
<head>
<link rel="stylesheet" type="text/css" href="/css/upload.css" />
<script src="/js/socket.io.js"></script>
<script type="text/javascript" charset="utf-8">
var socket = io.connect("/", { path: "/app/socket.io" });
var SelectedFiles = [];
var SelectedFile = 0;
var paused = 0;
var FReader;
var dat;
window.addEventListener("load", Ready);
function Ready() {
//...
}
function handleUploads() {
//...
}
function StartUpload(Name, size) {
FReader.onload = function(evnt) {
socket.emit("Upload", {
//...
});
};
socket.emit("Start", {
//...
});
}
function getBlocks(data) {
//...
}
socket.on("MoreData", function(data) {
//...
});
function UpdateBar(percent) {
//...
}
socket.on("Done", function(data) {
//...
});
function Refresh() {
location.reload(true);
}
</script>
</head>
<body>
//...
First of all I moved the JS code content in a new JS file named "upload-script.js" and then used "React Helmet" module (https://www.npmjs.com/package/react-helmet) in order to load them in document head during component rendering:
My code
return (
<Row className="mb-4">
<Helmet>
<link rel="stylesheet" type="text/css" href="/css/upload.css" />
<script src="/js/socket.io.js" />
<script src="/upload-script.js" />
</Helmet>
<Colxx xxs="12">
Checking on browser the module correctly adds the scripts in the document head, but come out the following error:
./src/containers/form-validations/upload-script.js
Line 2:14: 'io' is not defined no-undef
Line 124:3: Unexpected use of 'location' no-restricted-globals
The browser cannot compile the app because in the JS file "upload-script.js" contains variables that are only defined in the first script.. how can I solve it? Is this a good way to add the scripts in a React app?
Any suggestions or guidance would be greatly appreciated. Thank you in advance.

Import functions from another js file. Javascript

I have a question about including a file in javascript.
I have a very simple example:
--> index.html
--> models
--> course.js
--> student.js
course.js:
function Course() {
this.id = '';
this.name = '';
}
A student has a course property. like this:
import './course';
function Student() {
this.firstName = '';
this.lastName = '';
this.course = new Course();
}
and the index.html is like:
<html>
<head>
<script src="./models/student.js" type="text/javascript"></script>
</head>
<body>
<div id="myDiv">
</div>
<script>
window.onload= function() {
var x = new Student();
x.course.id = 1;
document.getElementById('myDiv').innerHTML = x.course.id;
}
</script>
</body>
</html>
But I am getting an error on the line "var x = new Student();":
Student is not defined
When I remove the import from Student, I don't receive the error anymore.
I have tried to use (require, import, include, create a custom function, export) and none has worked for me.
Anybody knows why? and how to fix that?
P.S. the path is correct, it comes from the autocomplete in VS Code
The following works for me in Firefox and Chrome. In Firefox it even works from file:///
models/course.js
export function Course() {
this.id = '';
this.name = '';
};
models/student.js
import { Course } from './course.js';
export function Student() {
this.firstName = '';
this.lastName = '';
this.course = new Course();
};
index.html
<div id="myDiv">
</div>
<script type="module">
import { Student } from './models/student.js';
window.onload = function () {
var x = new Student();
x.course.id = 1;
document.getElementById('myDiv').innerHTML = x.course.id;
}
</script>
You can try as follows:
//------ js/functions.js ------
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ js/main.js ------
import { square, diag } from './functions.js';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
You can also import completely:
//------ js/main.js ------
import * as lib from './functions.js';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
Normally we use ./fileName.js for importing own js file/module and fileName.js is used for importing package/library module
When you will include the main.js file to your webpage you must set the type="module" attribute as follows:
<script type="module" src="js/main.js"></script>
For more details please check ES6 modules
By default, scripts can't handle imports like that directly. You're probably getting another error about not being able to get Course or not doing the import.
If you add type="module" to your <script> tag, and change the import to ./course.js (because browsers won't auto-append the .js portion), then the browser will pull down course for you and it'll probably work.
import './course.js';
function Student() {
this.firstName = '';
this.lastName = '';
this.course = new Course();
}
<html>
<head>
<script src="./models/student.js" type="module"></script>
</head>
<body>
<div id="myDiv">
</div>
<script>
window.onload= function() {
var x = new Student();
x.course.id = 1;
document.getElementById('myDiv').innerHTML = x.course.id;
}
</script>
</body>
</html>
If you're serving files over file://, it likely won't work. Some IDEs have a way to run a quick sever.
You can also write a quick express server to serve your files (install Node if you don't have it):
//package.json
{
"scripts": { "start": "node server" },
"dependencies": { "express": "latest" }
}
// server/index.js
const express = require('express');
const app = express();
app.use('/', express.static('PATH_TO_YOUR_FILES_HERE');
app.listen(8000);
With those two files, run npm install, then npm start and you'll have a server running over http://localhost:8000 which should point to your files.
//In module.js add below code
export function multiply() {
return 2 * 3;
}
// Consume the module in calc.js
import { multiply } from './modules.js';
const result = multiply();
console.log(`Result: ${result}`);
// Module.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Module</title>
</head>
<body>
<script type="module" src="./calc.js"></script>
</body>
</html>
Its a design pattern same code can be found below, please use a live server to test it else you will get CORS error
https://github.com/rohan12patil/JSDesignPatterns/tree/master/Structural%20Patterns/module

How to pass an object to an module in require.js?

I have these js files:
main.js:
requirejs(['app']);
app.js:
define(['messages'], function (messages) {
alert(messages.getHello());
});
messages.js:
define(['global'],function () {
var privateFn = global.getObj()
return {
getHello: function () {
if(privateFn.hello == "test!")
return 'Hello World';
}
};
});
global.js:
define(function () {
var stateObj = {hello:"test!"};
return {
getObj: function () { return stateObj; }
};
});
and index.html as:
<!DOCTYPE html>
<html>
<head>
<!-- Include the RequireJS library. We supply the "data-main" attribute to let
RequireJS know which file it should load. This file (scripts/main.js) can
be seen as the entry point (main) of the application. -->
<script data-main="scripts/main" src="lib/require.js"></script>
</head>
<body>
<h1>Example 2: load module using explicit dependency syntax</h1>
</body>
</html>
However when I open index.html, I get the below error in console:
Uncaught ReferenceError: global is not defined messages.js
where I'm making mistake?
You just need to set global as an argument to messages.js' function. requirejs will pass it in for you.
messages.js:
define(['global'],function (global) {
var privateFn = global.getObj()
return {
getHello: function () {
if(privateFn.hello == "test!")
return 'Hello World';
}
};
});
This has the neat side effect that it is impossible to reference a module without declaring it as a dependency.

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