Is it possible to link a node.js file to HTML? - javascript

Very new to using html, I was wondering if it is possible to link a node file to HTML. I want to have a button which when clicked will run a function defined in the node file. I'm wondering if my node file has node packages if anything will go wrong. Anything helps!

I think you are trying to do something like the following: You have some code that is written to run in Node. Let's assume the code is contained in a file aModule.js. The question is, how do you invoke functions defined in that file from within the browser. And the second question is, will they run?
First, you can certainly import aModule.js into your browser just like any other javascript, using a script tag. Then you might be able to access the functions within the module, and they might run correctly in the browser. It all depends whether they were written with browser support in mind. I give an example below of one way (not the only way) that this can be done.
You will have to look at the particular code you are working with to see how you might be able to access it within the browser. Also, if the code is written to rely on features that are only available within node, you will have to do more work, probably modify the code, to get it to run.
At some point the "import" mechanism will be standardized so this will all get easier, but as of right now its a bit of a mess.
Here is an example of a module that will work in either node or in the browser.
// aModule.js - illustrates modularity that will work in browser or node
"use strict";
var aModule = {}; // In browser, this will put aModule into global context
// "Closure" stops other stuff from being put into global context in browser
(function () {
function getMessage() {
return "Hello";
}
// other internal code not intended to be exposed can go here...
// ...
// and here is how we expose our getMessage function
aModule.getMessage = getMessage;
})();
// If we are in node...
if (typeof module !== 'undefined' && module.exports) {
// Export our module for use in node
module.exports = aModule;
}
Here is how you access the functionality in node.js:
var aModule = require("./aModule.js");
console.log (aModule.getMessage());
And here is how you access it within the browser:
<!DOCTYPE html>
<html>
<head>
<title>Try out modularizing javascript in browser</title>
</head>
<body>
<h2>Try modularization...</h2>
<script src="aModule.js"></script>
<script>
alert(aModule.getMessage());
</script>
</body>
</html>
One more tip - take a look at tools like Browserify. These are designed to convert node code into a form that can run in browser. Your mileage may vary.

Related

Is there a way to read JS code as part of a JS file from another JS file ? (The app uses NodeJS)

I am working on a web app using NodeJS. The concept is : the main structure, to which you add the tools you want depending on what you want in your app.
To achieve that, I want my main JS file (index.js) to read the content of another file (tool.js) as if it was part of the code.
I know I can require a module in NodeJS and call a function from it, but this isn't what I want as I don't want to put the content of the file in a function. Here is an example of what I would like to achieve :
tool.js :
// tool.js
// This executes various actions.
var web_func = require(web_funcs.js); // another module, not important
web_func.executeAction();
console.log('whatever');
index.js :
// index.js
// This is the main file
/*Here I want to call tool.js*/
The goal is to have index.js be read as this :
// index.js
// This is the main file
// tool.js
// This executes various actions.
var web_func = require(web_funcs.js); // another module, not important
web_func.executeAction();
console.log('whatever');
The reason behind this is that I want my mainframe to be easy to deploy with minimal adjustments, and everything regarding the tools to be handled in a different file to make it easier to read.
And since there are several tools and the number will probably grow, I want it to be easily set-up.
If you have any idea or solution, please let me know, as it would be of great help. I've tried looking around but didn't find anything.
EDIT : changed the title of the question for better clarity.
You can read the file first and then use the eval() method to execute the code in string.
Read the code and call eval using this sample:
my-file.js
var a = "test";
console.log(a);
Code:
var fs = require('fs');
var code = fs.readFileSync('my-file.js', 'utf8');
eval(code);
Output:
test
Edit 1:
You can also reuse the variables from the other file in this way. For example, add console.log(a) after the eval(code) line.
...
eval(code);
console.log(a);
The output will be:
test
test

How do I detect when Emscripten's generated .js finishes loading the wasm so I can run my JS functions which call it?

I'm using Emscripten to compile some C code to WebAssembly. This is the final emcc call in my Makefile:
emcc $(CFLAGS) iva.a -o iva.js
Which works as intended and generates a .js file and a .wasm file. The JS is loaded into my HTML page as follows:
<script src="../dist/iva.js">
And it loads and instantiates the WebAssembly code iva.wasm properly. This message appears in the console soon after I load the page:
Fetch finished loading: GET "http://localhost:6931/dist/iva.wasm".
Which I take to mean that my WebAssembly is loaded through a fetch() and, perhaps pending some processing, I can access my functions through the console:
Module._init_display_system()
And get the return values. This holds true and everything works.
Clearly, I should be able to do this through a script as well. However, I can't see a way to only run a function after my WebAssembly has been instantiated. I get the feeling that I'm missing something rather obvious.
Anyway, how do I do this?
Use Module['onRuntimeInitialized'].
Module['onRuntimeInitialized'] = function() {
console.log("wasm loaded ");
var x=Module.ccall("doubleIt","number",["number"],[20]);
alert(x);
}
You have used emsdk, there are online WASM compilers like Wasmfiddle. Find my github repo useful for both the methods.
While the two solutions of Sudhakar RS and Anil8753 are totally fine, I want to add, that you have to execute this approach before you load your WebAssembly. Otherwise it might be too late to catch the event.
Besides that, there is another approach, which uses promises. If you add
-s MODULARIZE=1 -s 'EXPORT_NAME="createMyModule"'
as options when compiling with emcc, your resulting .js will contain the function createMyModule. This function will return a Promise that resolves as soon as your WebAssembly code is ready to use. Example usage:
In your HTML, add your WebAssembly as you already did:
<script src="../dist/iva.js">
In your js, call the function and after the promise resolved, you are good to go:
createMyModule().then(MyModule => {
console.log('WebAssembly loaded!');
// Access your functions (if bound by Embind):
console.log(MyModule.getSomething());
});
<script>
var Module = {
onRuntimeInitialized: function() {
console.log('module loaded');
}
};
</script>

Javascript Runtime Error: 'Application is undefined'

I need to know if this is correct. I'm just beginning in app development using WinJS. I've identified the source of the problem and got rid of it but I don't know if that's the correct method.Please help!
// Optimize the load of the application and while the splash screen is
// shown, execute high priority scheduled work.
ui.disableAnimations();
var p = ui.processAll().then(function () {
//return nav.navigate(nav.location || Application.navigator.home, nav.state);
return nav.navigate(nav.location || app.local, nav.state)
}).then(function () {
return sched.requestDrain(sched.Priority.aboveNormal + 1);
}).then(function () {
ui.enableAnimations();
});
The problem is in the first .then(). The commented line was the default line, I've changed it for the app to work.I've absolutely no idea what it is.Please tell me what it means and what is changed. By the way, 'app' is WinJS.Application and Application is a WinJS namespace in navigator.js where the home property is located.
This error would suggest that navigator.js isn't being loaded by the time this code is executed. The Application namespace, which is entirely arbitrary and unrelated to WinJS.Application, is defined only in navigator.js, so if that file isn't loaded that namespace won't exist.
A WinJS namespace, by the way, is just a formalization of a module pattern in JavaScript that helps you keep the global namespace from getting cluttered. Declaring a namespace like navigator.js does it:
WinJS.Namespace.define("Application", {
PageControlNavigator: WinJS.Class.define(
just creates a single object in the global namespace called "Application" and then defines members for it. (You can change "Application" to anything you want, by the way. Nothing else in navigator.js relies on it, and navigator.js is something that comes from the app templates in Visual Studio and isn't part of WinJS itself.)
So again, my suspicion is that you don't have (or whatever the proper path is) in your default.html, the path to it isn't correct, or that perhaps it's being loaded after the other code is trying to execute. Try setting breakpoints on WinJS.Namespace.define and see if that file is loaded and the breakpoint gets hit.

IPython: Adding Javascript scripts to IPython notebook

As a part of a project, I need to embedd some javascripts inside an IPython module.
This is what I want to do:
from IPython.display import display,Javascript
Javascript('echo("sdfds");',lib='/home/student/Gl.js')
My Gl.js looks like this
function echo(a){
alert(a);
}
Is there some way so that I can embed "Gl.js" and other such external scripts inside the notebook, such that I dont have to include them as 'lib' argument everytime I try to execute some Javascript code which requires to that library.
As a very short-term solution, you can make use of the IPython display() and HTML() functions to inject some JavaScript into the page.
from IPython.display import display, HTML
js = "<script>alert('Hello World!');</script>"
display(HTML(js))
Although I do not recommend this over the official custom.js method, I do sometimes find it useful to quickly test something or to dynamically generate a small JavaScript snippet.
Embedding D3 in an IPython Notebook
https://blog.thedataincubator.com/2015/08/embedding-d3-in-an-ipython-notebook/
To summarize the code.
Import the script:
%%javascript
require.config({
paths: {
d3: '//cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min'
}
});
Add an element like this:
%%javascript
element.append("<div id='chart1'></div>");
Or this:
from IPython.display import Javascript
#runs arbitrary javascript, client-side
Javascript("""
window.vizObj={};
""".format(df.to_json()))
IPython Notebook: Javascript/Python Bi-directional Communication
http://jakevdp.github.io/blog/2013/06/01/ipython-notebook-javascript-python-communication/
A more extensive post explaining how to access Python variables in JavaScript and vice versa.
I've been fighting with this problem for several days now, here's something that looks like it works; buyer beware though, this is a minimal working solution and it's neither pretty nor optimal - a nicer solution would be very welcome!
First, in .ipython/<profile>/static/custom/myScript.js, we do some require.js magic:
define(function(){
var foo = function(){
console.log('bar');
}
return {
foo : foo
}
});
Copy this pattern for as many functions as you like. Then, in .ipython/<profile>/static/custom/custom.js, drag those out into something persistent:
$([IPython.events]).on('notebook_loaded.Notebook', function(){
require(['custom/myScript'], function(custom){
window.foo = custom.foo;
} );
});
Yes, I am a horrible person for throwing stuff on the window object, namespace things as you deem appropriate. But now in the notebook, a cell like
%%javascript
foo();
should do exactly what it looks like it should, without the user having to explicitly import your JS. I would love to see a simpler solution for this (plz devs can we plz have $.getScript('/static/custom/util.js'); in custom.js to load up a bunch of global JS functions) - but this is the best I've got for now. This singing and dancing aside, HUGE ups to the IPython notebook team, this is an awesome platform!
Not out of the box by installing a package, at least for now.
The way to do it is to use custom.js and jQuery getScript to inject the js into the notebook.
I explicitly stay vague on how to do it, as it is a dev feature changing from time to time.
What you should know is that the static folder in user profile is merged with webserver static assets allowing you to access any file that are in this folder by asking for the right url.
Also this question has been asked a few hours ago on IPython weekly video "lab meeting" broadcasted live and disponible on youtube (you might have a longer answer), I've opened discussion with the author of the question here
For some reason, I have problems with IPython.display.Javascript. Here is my alternative, which can handle both importing external .js files and running custom code:
from IPython.display import display, HTML
def javascript(*st,file=None):
if len(st) == 1 and file is None:
s = st[0]
elif len(st) == 0 and file is not None:
s = open(file).read()
else:
raise ValueError('Pass either a string or file=.')
display(HTML("<script type='text/javascript'>" + s + "</script>"))
Usage is as follows:
javascript('alert("hi")')
javascript(file='Gl.js')
javascript('echo("sdfds")')
You can use IJavascript (a Javascript kernel for Jupyter notebooks).
I was interested in calling JavaScript from a Jupyter code (Python) cell to process strings, and have the processed string output in the (same) code cell output; thanks to Inject/execute JS code to IPython notebook and forbid its further execution on page reload and Why cannot python call Javascript() from within a python function? now I have this example:
from IPython.display import display, Javascript, Markdown as md, HTML
def js_convert_str_html(instring_str):
js_convert = """
<div id="_my_special_div"></div>
<script>
var myinputstring = '{0}';
function do_convert_str_html(instr) {{
return instr.toUpperCase();
}}
document.getElementById("_my_special_div").textContent = do_convert_str_html(myinputstring);
</script>
""".format(instring_str)
return HTML(js_convert)
jsobj = js_convert_str_html("hello world")
display(jsobj)
Note that the JavaScript-processed string does not get returned to Python per se; rather, the JavaScript itself creates its own div, and adds the result of the string conversion to it.

how should I write my define to work with curl.js?

I'm reading Addy Osmani's excellent blog post about writing AMD modules. I start with a simple chunk of js that I lifted from his post:
define('modTest', [],
// module definition function
function () {
// return a value that defines the module export
// (i.e the functionality we want to expose for consumption)
// create your module here
var myModule = {
doStuff:function(){
console.log('Yay! Stuff');
}
}
return myModule;
}
);
I took out the dependencies on foo and bar. Just want a simple object that logs to the console.
So I save that in /js/modTest.js and then try to load it:
curl(['/js/modTest.js'])
.then(function(mt) {
console.log("Load complete");
console.log("mt:");
console.log(mt);
mt.doStuff()
}, function(ex) {alert(ex.message);})
Result: error: Multiple anonymous defines in URL. OK that didn't work. Tried adding in a namespace: define('myCompany/modTest', [],, same result. Tried adding an empty string in the dependency array, same result.
Also tried curl(['modTest.js'], function(dep){console.log(dep)}); with the same result.
Is the code in Addy's blog post incorrect? Am I doing something wrong? Maybe a bug in curl?
Update 5/24: I ditched curl.js in favor of require.js. Zero odd errors, very little work to change over. I did have to deal with amdefine a bit to get my code running client and server side (one object is in both places, so grunt had to be configured to take care of that). My defines generally look like:
define(->
class AlphaBravo
...
And never have any trouble loading.
You asked curl() to fetch a module called "/js/modTest.js". It found the file and loaded it and found a module named "modTest", so it complained. :) (That error message is horribly wrong, though!)
Here's how you can fix it (pick one):
1) Remove the ID from your define(). The ID is not recommended. It's typically only used by AMD build tools and when declaring modules inside test harnesses.
2) Refer to the module by the ID you gave it in the define(). (Again, the ID is not recommended in most cases.)
curl(['modTest'], doSomething);
3) Map a package (or a path) to the folder with your application's modules. It's not clear to me what that would be from your example since modTest appears to be a stand-alone module. However, if you were to decide to organize your app's files under an "app" package, you packages config might look like this:
packages: [ { name: 'app', location: 'app' } ]
Then, when you have code that relies on the modTest module, you can get to it via an ID of "app/modTest".
curl(['app/modTest'], doSomething);
I hope that helps clear things up!
Fwiw, Addy's example could actually work with the right configuration, but I don't see any configuration in that post (or my eyes missed it). Something like this might work:
packages: [ { name: 'app', location: '.' } ]
-- John
I've just had a similar problem which turned out to be the include order I was using for my other libraries. I'm loading handlebars.js, crossroads.js, jquery and a few other libraries into my project in the traditional way (script tags in head) and found that when I place the curl.js include first, I get this error, but when I include it last, I do not get this error.
My head tag now looks like this:
<script type="text/javascript" src="/js/lib/jquery.js"></script>
<script type="text/javascript" src="/js/lib/signals.js"></script>
<script type="text/javascript" src="/js/lib/crossroads.js"></script>
<script type="text/javascript" src="/js/lib/handlebars.js"></script>
<script type="text/javascript" src="/js/lib/curl.js"></script>
<script type="text/javascript" src="/js/main.js"></script>
You have a problem with your define call. It is NAMED
See AMD spec for full story on how to write defines, but here is what I would expect to see in your js/modTest.js file:
define(/* this is where the difference is */ function () {
// return a value that defines the module export
// (i.e the functionality we want to expose for consumption)
// create your module here
var myModule = {
doStuff:function(){
console.log('Yay! Stuff');
}
}
return myModule;
}
);
Now, the boring explanation:
CurlJS is awesome. In fact, after dealing with both, RequireJS and CurlJS, I would say CurlJS is awesome-er than RequireJS in one category - reliability of script execution ordering. So you are on the right track.
On of the major things that are different about CurlJS is that it uses "find at least one anonymous define per loaded module, else it's error" logic. RequireJS uses a timeout, where it effectively ignores cases where nothing was defined in a given file, but blows up on caught loading / parsing errors.
That difference is what is getting you here. CurlJS expects at least one anonymous (as in NOT-named) define per loaded module. It still handles named defines fine, as expected. The second you move the contents of "js/modTest.js" into inline code, you will have to "name" the define. But, that's another story.

Categories

Resources