NodeJS HTML: 'require' is undefined - javascript

I've been working on a NodeJS login/register script (called LoginRegister.js) that seemed to work fine in the terminal. I've also installed NodeJS, and the bcrypt module for it. Here's the file:
// Initialization
var fs = require("fs");
var bcrypt = require("bcrypt");
var LUinputID = $("#LUsernameIn").value;
var LPinputID = $("#LPasswordIn").value;
var RUinputID = $("#RUsernameIn").value;
var RPinputID = $("#RPasswordIn").value;
var UserStorageTextFile = "Users.txt";
$(document).ready(function(){
console.log("Hello");
var RButton = $("rBTN").addEventListener("click", registerUser(UserStorageTextFile, RUinputID, RPinputID));
var LButton = $("#lBTN").addEventListener("click", registerUser(UserStorageTextFile, LUinputID, LPinputID));
});
// Defining Functions
function encrypt(passwordFromUser) {
var salt = bcrypt.genSaltSync(10);
var hash = bcrypt.hashSync(passwordFromUser, salt);
return hash;
}
function passCheck(passwordFromUser, passHashed){
return bcrypt.compareSync(passwordFromUser,passHashed);
}
function loginUser(usersTextFile, username, password){
data = fs.readFileSync(usersTextFile).toString();
if(data.indexOf(username) != -1){
console.log(data.indexOf(username));
for (var i = 0; i <= data.indexOf(username); i++) {
if (i == data.indexOf(username)) {
i += (username.length + 1);
passcode = data.slice(i, i+60);
if (passCheck(password, passcode)) {
console.log("Yes!!");
}
else{
console.log("No!!");
}
}
}
}
else{
console.log("No!!");
}
}
function registerUser(usersTextFile, username, password) {
data = fs.readFileSync(usersTextFile);
saveData = data + username + "-" + encrypt(password) + "\n";
fs.writeFile('Users.txt', saveData, (err2) => {
console.log("User " + username + " Registered!");
});
}
I wanted to test it in a browser, so I put together an html file to display my JS one in action:
<!DOCTYPE html>
<html>
<head>
<title>Authentication Test</title>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="LoginRegister.js"></script>
</head>
<h2>Login</h2>
<input type="text" id="RUsernameIn">
<input type="password" id="RPasswordIn">
<button id="lBTN">Login</button>
<h2>Register</h2>
<input type="text" id="LUsernameIn">
<input type="password" id="LPasswordIn">
<button id="rBTN">Register</button>
</html>
I opened up the HTML file in Microsoft Edge and tried pressing the register button after putting in details into the boxes, but I checked the Users.txt file and nothing had happened. After looking at the F12 Developer Tools, I noticed that on startup, the console stated:
SCRIPT5009: 'require' is undefined
LoginRegister.js (2,1)

Node.JS is a server-side technology, not a browser technology. Thus, Node-specific calls, like require(), do not work in the browser.
See browserify or webpack if you wish to serve browser-specific modules from Node.
See more: require is not defined? node.js
Thank Rob Raisch.

Related

Calling external JavaScript function in full stack app

I have used JavaScript for a while, but am brand new to Node.js and full stack development, taking on a small project as a hobbyist. I have Heroku set up to host the app at https://midi-writer.herokuapp.com/ and am able to edit my files and update the app (using git commands) through my Mac terminal.
I am having trouble figuring out how to call a JavaScript function in an external file (in /src/js/midiWriter.js) from the index.html page. Using <script type="text/javascript" src="bundle.js"></script> doesn't work (I think that the file is 'bundled' when I push it to Heroku), and I have also tried <script type="text/javascript" src="../src/js/midiWriter.js"></script>
Here is the full code for index.html with the function call at the end of the script.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Heart Beats</title>
<style>
</style>
</head>
<body>
<script type="text/javascript" src="bundle.js"></script>
<link rel="stylesheet" type="text/css" href="style.css"></link>
<form id="jsonFile" name="jsonFile" enctype="multipart/form-data" method="post">
<fieldset>
<h2>EKG File</h2>
<input type='file' id='fileinput'>
<input type='button' id='btnLoad' value='Load' onclick='loadFile();'>
<hr>
Frequency: <div id="frequency"></div>
Metadata:<div id="metaData"></div>
<div id="midiDownload">A link will appear here after the file has been processed</div>
</fieldset>
</form>
<script type="text/javascript">
function loadFile() {
var input, file, fr;
if (typeof window.FileReader !== 'function') {
alert("The file API isn't supported on this browser yet.");
return;
}
input = document.getElementById('fileinput');
if (!input) {
alert("Um, couldn't find the fileinput element.");
}
else if (!input.files) {
alert("This browser doesn't seem to support the `files` property of file inputs.");
}
else if (!input.files[0]) {
alert("Please select a file before clicking 'Load'");
}
else {
file = input.files[0];
fr = new FileReader();
fr.onload = receivedText;
fr.readAsText(file);
}
function receivedText(e) {
let lines = e.target.result;
var newArr = JSON.parse(lines);
var metaDataString = '';
document.getElementById("frequency").innerHTML = newArr.frequency + " Hz";
for (i = 0; i < newArr.meta.dashboard_measurements.length; i++){
metaDataString += newArr.meta.dashboard_measurements[i].description + ": "
+ newArr.meta.dashboard_measurements[i].value
+ " " + newArr.meta.dashboard_measurements[i].unit + "<br>";
}
document.getElementById("metaData").innerHTML = metaDataString;
}
midiWriter();
}
</script>
</body>
</html>
Here's the midiWriter.js file:
function midiWriter(){
var MidiWriter = require('midi-writer-js');
var track = new MidiWriter.Track();
track.addEvent([
new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'}),
new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'}),
new MidiWriter.NoteEvent({pitch: ['C4', 'C4', 'C4', 'C4', 'D4', 'D4', 'D4', 'D4'], duration: '8'}),
new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'})
], function(event, index) {
return {sequential: true};
}
);
var write = new MidiWriter.Writer(track);
console.log(write.dataUri());
var app = document.getElementById('midiDownload');
var downloadLink = `Download Link`;
app.innerHTML = downloadLink;
}
I get the Uncaught Reference Error "midiWriter is not defined" with this version.
Please excuse any lame errors! I am brand new to this :)
Simple solution would be like this:
In your html file:
<script src="../src/js/midiWriter.js"></script>
<script>
...
midiWriter();
</script>
What the first line does is set the source of the file you will use and the in the plain script tags, you can use any function or variable that has global scope and is declared in the file whose path you declared in the <script src=""> tag.
Just hired someone on Fiverr to take a look. The problem is that I need to define the external function globally using window.midiWriter = function (){...

Chrome ShapeDetetion API BarcodeDetector works with javascript but not with typescript

I want to implement the BarcodeDetector in an Angular app. I tested out the API with the following code:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="./script.js"></script>
</head>
<body>
<button onclick="scan()">Click me</button>
<img src="./barcode.gif">
<pre></pre>
</body>
</html>
JavaScript:
function scan() {
const images = document.querySelectorAll('img');
const pres = document.querySelectorAll('pre');
try {
pres[0].textContent += 'started\n';
let barcodeDetector = new BarcodeDetector();
pres[0].textContent += 'created and detecting\n';
barcodeDetector.detect(images[0]).then(detectedCodes => {
for (const barcode of detectedCodes) {
pres[0].textContent += barcode.rawValue + '\n';
}}).catch((e) => {
pres[0].textContent += e + '\n';
});
} catch (e) {
pres[0].textContent += e + '\n';
}
}
and it works perfectly. On the PC I got a NotSupported error and the decoded barcode when I opened the page on my phone.
Since TypeScript is a superset of JavaScript I tought that it should be quite simple to port the code but, apparently it isn't. The HTML in the angular app pretty much the same. The component code is the following:
var BarcodeDetector: any;
#Component({
templateUrl: './index.component.html'
})
export class IndexComponent {
#ViewChild('imgRef')
image: ElementRef;
hasBarcodeDetector = '';
errors = '';
scanData = '';
constructor() {
try {
this.hasBarcodeDetector = 'BarcodeDetector' in window ? 'true' : 'false';
const barcodeDetector = new BarcodeDetector();
barcodeDetector.detect(this.image.nativeElement).then(detectedCodes => {
for (const barcode of detectedCodes) {
this.scanData += barcode.rawValue + '\n';
}
});
} catch (e) {
this.errors = e;
}
}
}
The check whether the detector exists works, because I get true, but both on PC and mobile I get the following error:
TypeError: (void 0) is not a constructor
I'm guessing it has something to do with the declaration of the decoder, but I really have no idea on what to do.
I think with your variable you're accidentally overwriting the window.BarcodeDetector. Also note that you're not making use of the result of the feature detection. Feature detection, by the way, should happen differently now, as outlined in the recently updated article:
await BarcodeDetector.getSupportedFormats();
/* On a macOS computer logs
[
"aztec",
"code_128",
"code_39",
"code_93",
"data_matrix",
"ean_13",
"ean_8",
"itf",
"pdf417",
"qr_code",
"upc_e"
]
*/
This allows you to detect the specific feature you need, for example, QR code scanning:
if (('BarcodeDetector' in window) &&
((await BarcodeDetector.getSupportedFormats()).includes('qr_code'))) {
console.log('QR code scanning is supported.');
}

Pass a variable from web app and display dialog

I am trying to pass a searchterm from a google web app to display the results. I am having trouble on submission I receive a blank screen. When the form is submitted, I would like it to display the results. The main code works within the logger- now I am just working on the UI and getting the form to work.
Any help is appreciated!
So far this is the code I have:
CODE:
function SearchFiles() {
//Please enter your search term in the place of Letter
var searchterm ="'mysearchinput'"; \\ this would be the variable that is passed from the form on index.html
var searchFor ="title contains " + searchterm;
var owneris ="and 'youremail#yourdomain.com' in Owners";
var names =[];
var fileIds=[];
var files = DriveApp.searchFiles(searchFor + owneris);
while (files.hasNext()) {
var file = files.next();
var fileId = file.getId();// To get FileId of the file
fileIds.push(fileId);
var name = file.getName();
names.push(name);
}
for (var i=0;i<names.length;i++){
Logger.log(names[i]);
Logger.log("https://drive.google.com/uc?export=download&id=" + fileIds[i]);
}
}
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function processForm(formObject) {
Logger.log('I was called!');
// here is where I would like to display results of searthterm.
}
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(updateUrl).processForm(formObject);
}
function onFailure(error) {
var div = document.getElementById('output');
div.innerHTML = "ERROR: " + error.message;
}
</script>
</head>
<body>
Hello, World!
<form id="myForm" onsubmit="handleFormSubmit(this)">
<input type="text" name="search">
<input type="submit" value="Submit" />
</form>
<input type="button" value="Close"
onclick="google.script.host.close()" />
SEARCH FUNCTION:
function SearchFiles() {
Logger.log('I Searched Files');
//Please enter your search term in the place of Letter
var searchterm ="'Whatevertextisinthesearchbox'";
var searchFor ="title contains " + searchterm;
var owneris ="and 'Youremail#yourdomain' in Owners";
var names =[];
var fileIds=[];
var files = DriveApp.searchFiles(searchFor + owneris);
while (files.hasNext()) {
var file = files.next();
var fileId = file.getId();// To get FileId of the file
fileIds.push(fileId);
var name = file.getName();
names.push(name);
}
for (var i=0;i<names.length;i++){
// Logger.log(names[i]);
// Logger.log("https://drive.google.com/uc?export=download&id=" + fileIds[i]);
var filesreturned = {
name:names[i],
urls:"https://drive.google.com/uc?export=download&id=" + fileIds[i]
}
Logger.log(filesreturned.name + " - " + filesreturned.urls);
return(filesreturned);
}
}
As per your comment above, here is the code to simply show hello world on button click. For your reference, I have also added a code to pass data between javascript and appscript.
Index.html file
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function displayMessage()
{
google.script.run.withSuccessHandler(helloWorld).parseDataFromAppscript();
}
function helloWorld(stringText)
{
document.writeln(stringText);
}
</script>
</head>
<body>
<input type="button" value="submitButton" name="submitButton" onclick="displayMessage()"/>
</body>
</html>
Code.gs file
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Index');
return template.evaluate()
.setTitle('Hello World')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function parseDataFromAppscript()
{
return "Hello World!";
}
To run this, go to publish -> deploy as web app -> update. And then click latest code.
If you want explanation for any part, please feel free to ask. I'm assuming you already know html javascript and google.script.run method. :)

Node.js writeFile [Uncaught TypeError: Cannot read property 'writeFile' of undefined]

I can't get writeFile to write file. It works find if it's not in a function so it's not the module but when the function is called, it results in an error.
[Uncaught TypeError: Cannot read property 'writeFile' of undefined]
JS Code:
var fs = require('fs');
var input = document.getElementById('filename');
var fileName = input.value;
function recordToFilename() {
var input = document.getElementById('filename');
var fileName = input.value;
var qw = fileName;
if (qw) {
alert('value of: ' + qw);
console.log(qw);
// demo output
var myObject = {
qw: qw,
fullN: function() {
return this.qw;
}
};
document.getElementById("demo").innerHTML = myObject.fullN();
var path = "danny.txt";
var data1 = "jdsfhadj"
fs.writeFile(path,data1)
//end demo output code
} else {
alert('Please enter a filename!');
input.focus();
}
};
HTML Code:
<html>
<head>
<title>writeFile</title>
<script src="jquery.js"></script>
<script src="bonescript.js"></script>
<script src="test_3.js"></script>
</head>
<body>
<label for="filename">Filename</label>
<input name="filename" id="filename" type="text">
<a id="enter_button" onclick="recordToFilename();" href="javascript:void(0);" title="enter">enter name</a>
<br>
<p id="demo"></p>
</body>
</html>
Please upgrade your node version to resolve this issue.

Namespace schema for JavaScript

I come from the world of Java. In Java there are packages, for example, "com.mycompany.billing" and classes that are inside the package, for example, "BillProcessor". The company in which I work is starting a new project and I need to decide on a good namespace schema. I'm thinking of projecting how it's done in Java to JavaScript, for example, having a namespace "com.mycompany.billing" and a class that's in a file like "BillProcessor.js". In addition, unit testing is vital so I need such a structure that is easy to unit test.
Can somebody suggest a good approach?
I think that I came up with a good solution, please advise. As an example I'll make a billing page. There are 4 files:
${root}/billing.html - contains an input box for the name on credit card
${root}/js/com/mycompany/common/common.js - initializes logging and error handling
${root}/js/com/mycompany/common/Url.js - class that is used to perform an AJAX call
${root}/js/com/mycompany/aproject/billing.js - initializes things on the billing page
So for example, common.js contains:
var com_mycompany_common_common = function() {
function log(message) {
console.log((new Date()) + ': ' + message);
}
function init() {
window.onerror = function(message) {
log('Unhandled error: ' + message);
}
}
return {
log: log,
init: init
}
} ();
$(document).ready(function() {
try {
com_mycompany_common_common.init();
} catch (e) {
console.log('Error during initialization: ' + e);
}
});
Url.js:
function com_mycompany_common_Url(url) {
this.url = url;
}
com_mycompany_common_Url.prototype.addParameter(name, value) {
this.url += '?' + name + '=' + value;
}
com_mycompany_common_Url.prototype.ajax() {
com_mycompany_common_common.log('Send ajax to: ' + this.url);
}
billing.js
var com_mycompany_aproject_billing = function() {
function init() {
$('#submitButton').click(function() {
Url url = new com_mycompany_common_Url('http://bla.com/process/billing');
var creditCardName = $('#ccName').val();
url.addParameter('name', creditCardName);
url.ajax();
}
}
return {init: init};
} ();
$(document).ready(function() {
try {
com_mycompany_aproject_billing.init();
} catch (e) {
console.log('Error during initialization: ' + e);
}
});
billing.html
<!DOCTYPE html>
<html>
<head>
<title>Billing</title>
</head>
<body>
Enter name on credit card: <input type="text" id="ccName" /><br><br>
<button id="submitButton">Submit Payment</button>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="js/com/mycompany/common/common.js"></script>
<script type="text/javascript" src="js/com/mycompany/common/Url.js"></script>
<script type="text/javascript" src="js/com/mycompany/aproject/billing.js"></script>
</body>
</html>
Most of the time people use the Object Literal pattern to achieve name spacing in JavaScript.
More info: http://msdn.microsoft.com/en-us/scriptjunkie/gg578608
You can "nest" namespaces like so:
var MyCompany = MyCompany || {};
MyCompany.Billing = MyCompany.Billing || {};
// etc...
Another ScriptJunkie article that covers some namespacing stuff: http://msdn.microsoft.com/en-us/scriptjunkie/hh377172.aspx
I'M POSTING THIS QUESTION ON https://codereview.stackexchange.com/questions/8393/approach-to-organizing-javascript-for-an-html-page MAYBE I'LL GET ANSWERS THERE.

Categories

Resources