I included a module in my js file. Now i defined a button in a ejs file, which calls a function in an external js file from the public folder. How can i use the module in this function?
I tried to pass the module as a parameter, but i didn´t work. Is this even the right way to use this module in my external file?
the route js file
var express = require("express");
var router = express.Router();
var R = require("r-integration");
/* GET home page. */
router.get("/", function (req, res, next) {
res.render("Upload", { title: "Upload", para: R });
});
module.exports = router;
my ejs file with the button which calls the function loadScript()
Here i also tried to pass the paramter para to the const rModule
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<button onClick="loadScript()">Test Skript</button>
</body>
<script>
const rModule = para;
</script>
<script src="/javascripts/rScriptTest.js"></script>
</html>
the external js file from the public folder.
But here it says, that rModule is not defined.
function loadScript() {
let result = rModule.executeRScript("./RScripts/test.r");
console.log(result);
}
You can't pass a function though an EJS template. It won't serialize cleanly.
You need:
A JS script/module that will run on a browser
A URL for that file (usually provided with express.static)
You fail at the first hurdle. The module you are trying to use describes itself thus:
This is the R-integration API which allows you to execute arbitrary R commands or scripts directly from the node JS environment. This integration works on Windows and GNU/Linux based systems and uses system calls to access the R binary.
There is no way that it is going to achieve that without using Node.js-specific APIs that are not available in the browser.
You could write a web service in Node.js and interact with it using Ajax instead.
I'm setting up a HTML page that want to use the data from CertStream.
The Javascript library is located at https://github.com/CaliDog/certstream-js
In the install instructions it says " if you're using this in the browser, just add dist/certstream.min.js to a tag, and interact with it as normal!".
I have therefor created a HTML page that uses this tag:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Certstream</title>
<meta name="viewport" content="width=device-width; initial-scale=1.0;"/>
<meta http-equiv="Content-Type" content="text/html; charset=UFT-8" />
</head>
<body>
<h1>CertStream</h1>
<!-- CertStream script -->
<script src="dist/certstream.min.js"></script>
<script>
const CertStreamClient = require('certstream');
let client = new CertStreamClient(function(message){
console.log("Received -> ", message)
});
client.connect();
</script>
<!-- //CertStream script -->
</body>
</html>
But I get the error:
Uncaught ReferenceError: require is not defined
http://localhost/certstream-js/test.html:15
certstream.min.js is located on in the folder "dist":
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.CertStream=t():e.CertStream=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var c=n[o]={exports:{},id:o,loaded:!1};return e[o].call(c.exports,c,c.exports,t),c.loaded=!0,c.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}function c(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),i=n(1),s=o(i),a=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];c(this,e),this.context={},this.callback=t,this.skipHeartbeats=n}return r(e,[{key:"connect",value:function(){var e=this;console.log("Connecting..."),this.ws=new s.default("wss://certstream.calidog.io/"),console.log("Created ws -> ",this.ws),this.ws.onmessage=function(t){console.log("onmessage called!");var n=JSON.parse(t.data);"heartbeat"===n.message_type&&e.skipHeartbeats||e.callback(t,e.context)},this.ws.onopen=function(){console.log("Connection established to certstream! Waiting for messages...")},this.ws.open()}}]),e}();t.default=a},function(e,t,n){var o,c,r;!function(n,i){c=[],o=i,r="function"==typeof o?o.apply(t,c):o,!(void 0!==r&&(e.exports=r))}(this,function(){function e(t,n,o){function c(e,t){var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,!1,!1,t),n}var r={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3,maxReconnectAttempts:null};o||(o={});for(var i in r)"undefined"!=typeof o[i]?this[i]=o[i]:this[i]=r[i];this.url=t,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var s,a=this,u=!1,l=!1,d=document.createElement("div");d.addEventListener("open",function(e){a.onopen(e)}),d.addEventListener("close",function(e){a.onclose(e)}),d.addEventListener("connecting",function(e){a.onconnecting(e)}),d.addEventListener("message",function(e){a.onmessage(e)}),d.addEventListener("error",function(e){a.onerror(e)}),this.addEventListener=d.addEventListener.bind(d),this.removeEventListener=d.removeEventListener.bind(d),this.dispatchEvent=d.dispatchEvent.bind(d),this.open=function(t){if(s=new WebSocket(a.url,n||[]),t){if(this.maxReconnectAttempts&&this.reconnectAttempts>this.maxReconnectAttempts)return}else d.dispatchEvent(c("connecting")),this.reconnectAttempts=0;(a.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",a.url);var o=s,r=setTimeout(function(){(a.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",a.url),l=!0,o.close(),l=!1},a.timeoutInterval);s.onopen=function(n){clearTimeout(r),(a.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","onopen",a.url),a.protocol=s.protocol,a.readyState=WebSocket.OPEN,a.reconnectAttempts=0;var o=c("open");o.isReconnect=t,t=!1,d.dispatchEvent(o)},s.onclose=function(n){if(clearTimeout(r),s=null,u)a.readyState=WebSocket.CLOSED,d.dispatchEvent(c("close"));else{a.readyState=WebSocket.CONNECTING;var o=c("connecting");o.code=n.code,o.reason=n.reason,o.wasClean=n.wasClean,d.dispatchEvent(o),t||l||((a.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","onclose",a.url),d.dispatchEvent(c("close")));var r=a.reconnectInterval*Math.pow(a.reconnectDecay,a.reconnectAttempts);setTimeout(function(){a.reconnectAttempts++,a.open(!0)},r>a.maxReconnectInterval?a.maxReconnectInterval:r)}},s.onmessage=function(t){(a.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",a.url,t.data);var n=c("message");n.data=t.data,d.dispatchEvent(n)},s.onerror=function(t){(a.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","onerror",a.url,t),d.dispatchEvent(c("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(t){if(s)return(a.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","send",a.url,t),s.send(t);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(e,t){"undefined"==typeof e&&(e=1e3),u=!0,s&&s.close(e,t)},this.refresh=function(){s&&s.close()}}if("WebSocket"in window)return e.prototype.onopen=function(e){},e.prototype.onclose=function(e){},e.prototype.onconnecting=function(e){},e.prototype.onmessage=function(e){},e.prototype.onerror=function(e){},e.debugAll=!1,e.CONNECTING=WebSocket.CONNECTING,e.OPEN=WebSocket.OPEN,e.CLOSING=WebSocket.CLOSING,e.CLOSED=WebSocket.CLOSED,e})}])});
//# sourceMappingURL=certstream.min.js.map
What they mean by
...if you're using this in the browser, just add dist/certstream.min.js to a tag, and interact with it as normal!
...is that you don't need the require call (require is CommonJS, not standard JavaScript, and not provided by default on browsers). If you just include the script file in your page, it defines a global CertStream object with a default property providing the default export of the module. (I suspected this was the case, so I grabbed a copy and tried it.)
The docs could be clearer.🙂 In particular, it looks like after including the library in the browser, you have to use CertStream.default rather than CertStreamClient. I'd probably do that by doing this up-front:
const CertStreamClient = CertStream.default;
(It's too bad they don't provide a native JavaScript module [ESM] file in their dist folder.)
I looked up into certstream.js module in the dist folder and it is a UMD module. Basically, a UMD module is a JavaScript file that tries to guess at runtime which module system it’s being used in, and then it acts as that kind of module. So you can load the file in a plain <script>, or you can load it from an AMD module loader, or you can load it as a Node.js module, and it will always do something sensible.
In your code since you have already loaded the module using <script> tag, the global CertStream object can be directly used without requiring the module again.
I'm working on a personal project in order to learn web dev, and I've run into a strange (and hopefully easily solved) problem. In my index.html file I've included a reference to a main.js file, and that's been working just fine for a while now. However, I've recently rewritten the project in Typescript and I've decided to rearrange the folder structure. The problem is that when I move my index.html file (and some other files) down one directory and append a '../' to the script's 'src' tag, I get a 404 error when the html attempts to load the script.
This works just fine:
.
|-scripts
|-Main.ts
|-Main.js
|-SlideShowView.ts
|-SlideShowView.js
|-Server.ts
|-Server.js
|-index.html -> <script src="scripts/Main.js" type="module"></script>
This does not:
.
|-scripts
|-Main.ts
|-Main.js
|-SlideShowView.ts
|-SlideShowView.js
|-services
|-Server.ts
|-Server.js
|-index.html -> <script src="../scripts/Main.js" type="module"></script>
Connecting to the site when using the second scheme gives this error:
GET http://localhost:8000/scripts/Main.js net::ERR_ABORTED 404 (Not Found)
Is index.html not allowed to look above it's own directory? Is there a permissions issue or something? It's such a simple thing that's failing to work I figure there must be something small I'm missing.
Thanks in advance for the help!
Found the answer!
After I moved index.html back to root, the problem wasn't in my html or main.js, but in the express server I was using:
import path from "path";
import express from "express";
const serverPortNum = 8000;
const htmlFile = path.join(__dirname + '/../index.html'); //Added an escape here...
// Create html server
var app = express();
app.use(express.static(__dirname));// ...but not here.
app.get('/', function(req: any, res: any)
{
res.sendFile(htmlFile);
});
app.listen(serverPortNum, function()
{
console.log("Listening! (port " + serverPortNum + ")");
});
Basically, I had changed the path to the html file correctly but I forgot to make the change in app.use() as well. Changing that line to app.use(express.static(__dirname + "/..")); corrected the problem.
This should be simple as moving the index.html file outside of both file structures
|-scripts
|-Main.ts
|-Main.js
|-SlideShowView.ts
|-SlideShowView.js
|-services
|-Server.ts
|-Server.js
|-index.html -> <script src="scripts/Main.js" type="module"></script>
I am trying to simply access a JavaScript file from within an HTML file using the script src attribute, and I have been unable to do so. Both files are in my functions folder.
I have the following Cloud Function index.js file in my functions folder:
const functions = require('firebase-functions');
const db = require('./admin');
var viewerApp = require('./viewerApp');
exports.view = functions.https.onRequest(viewerApp);
the viewApp.js file looks like this:
const express = require("express");
const fs = require('fs');
const viewerApp = express();
module.exports =
viewerApp.get('/:collection_name/:id', (req, res) =>
{
var viewerHTML = fs.readFileSync('./viewerApp.html').toString();
var id = req.params.id;
var collection_name = req.params.collection_name;
var rendered_HTML = eval(viewerHTML);
res.send(rendered_HTML);
}
)
You will notice the eval(viewerHTML) statement, which refers to a separate html file called viewerApp.html, which basically contains a template literal and looks like so:
<!DOCTYPE html>
<html lang="en">
<body>
...
</body>
</html>
(if someone has a better suggestion for separating the HTML into a separate file while being able to use ${variables} that would be helpful as well, as eval() is not ideal and perhaps is part of what is causing my problem)
The above works fine, except that I cannot figure out how to reference a JavaScript file located in the same functions folder, which means I would need to include all my JavaScript in the viewerApp.html file, which will be a mess.
I have tried all these possibilities in the viewerApp.html file (to try and refer to a JavaScript file called test.js):
<script src="./test.js"></script>
<script src="/test.js"></script>
<script src="test.js"></script>
<script src=test.js></script>
All of the above yield the following error in the console:
Uncaught SyntaxError: Unexpected token < test.js:2
(I get the same error if I try and refer to a filename that doesn't exist so I suspect a problem in the file path or limitation on the ability to access the local file system)
I don't know what to make of the error being related to a < character, as the content of test.js is simply:
console.log("logging happened");
Any assistance would be MUCH appreciated. Thank you!!
The problem in the end was that I did not initialize and configure firebase hosting which seems to be what allows html/js/css and other static files to be accessible in HTML returned from the cloud function. Once I did that and setup the public folder, I was able to refer to the test.js file by putting it in the public folder. That plus addition tweaks to the rewrite section of the firebase.json file, and I was all set. Following this video helped a lot and contains all the required steps.
I tried
script(src="/fusioncharts.charts.js")
in the head of layout.jade, but it didnt work, error 404.
Then I tried via
layout.jade:
script(src="/charts")
app.js:
app.get('/charts', routes.charts);
index.js:
exports.charts = function(req, res){
res.sendFile(__dirname + "fusioncharts/fusioncharts.charts.js");
};
I get error : res.sendFile is not a function.
I have enide2015, project created with node_modules from enide.
I tried with -- router.get( ... - I got property undefined error
layout.jade:
doctype html
html( lang="en" )
head
title= title
meta( charset='utf-8' )
meta( http-equiv='X-UA-Compatible', content='IE=edge' )
meta( name='viewport', content='width=device-width, initial-scale=1.0' )
meta( name='description', content='Baking Bootstrap Snippets with Jade' )
//- Bootswatch Theme
link(href='//maxcdn.bootstrapcdn.com/bootswatch
/3.3.6/flatly/bootstrap.min.css',rel='stylesheet')
script(src="https://www.google.com/jsapi")
script(src="http://maps.google.com/maps/api/js?sensor=true")
script(src='//ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js')
script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular-route.min.js')
//***************************
script(src="/fusioncharts")
//***************************
In other words, proper way to include external js local library, not CDN source ,ideally specifically fusioncharts ? Thank you.
EDIT: OK, found the problem, when creating node express project with Enide, there's pre-set environment in app.js, setting only PUBLIC folder accessible. I got now 200 OK message while accessing fusioncharts.js file.
I am still not able to render the chart itself, rendering ? Any suggestions ?
Found this trending on Reddit - talks about using FusionCharts with Node, Express and MongoDB.
http://www.fusioncharts.com/tutorials/creating-interactive-charts-using-node-express-and-mongodb/