How to access webpack created js functions in html - javascript

I have an express server that compiles handlebar files into html based on the route and I am using webpack to compile javascript files into one js file per page the user navigates to.
I am trying to access global functions that I defined in my javascript files from my html files to register onclick events and I can't seem to get it to work. The page loads fine
Here is the resulting HTML from the handlebars file:
<button onclick="OnButton_Open()">
Here is the function in the webpack compiled javascript:
OnButton_Open = function () {
here's my function
}
If I leave the function like above, the page loads, but when I click I get an error that it can't find OnButon_Open.
window.OnButton_Open = function () {
here's my function with the global prefix
}
If I prefix the function with window. which is what I thought that I had to do in this situation, I will actually get a reference error as the page loads that OnButon_Open is not defined. This is what the resulting webpack code looks like at the spot where I get the error:
/* harmony export (immutable) */ __webpack_exports__["OnButton_Open"] = OnButton_Open;
Is there a better way to make those functions accessible to the outside world? I'd happily put everything in the global scope for now until I can modularize this app a bit more.

Related

Trouble initializing a JavaScript module

Just trying and testing CKAN going through the documentation. So far so good but I'm having trouble initializing a JavaScript module.
I followed these steps, http://docs.ckan.org/en/latest/theming/javascript.html#initializing-a-javascript-module, restarted the server, loaded the page and the button is there, I can see the newly created JS file in the page but it's not being initialized so no output in the console.
If I add another console.log anywhere not inside initialize: function () {} in the JS file it gets outputted.
Maybe some other steps missing here? Do I need to register the CKAN module somewhere?

How to create global namespace/class in TypeScript that can be used in plain JavaScript?

My TypeScript and plain JavaScript code need to share a namespace and some data. TypeScript should "prepare" a namespace, external JS provides data, TypeScript processes it.
The context is an Angular 2 application. The loading order is:
Angular 2 app with its JavaScript starts
a custom external JavaScript file is dynamically loaded from an external source (JSONP style)
Angular 2 app does further processing on the data generated by the loaded JS file
Currently in the external JavaScript file I'm doing something like this:
if (typeof Blog === 'undefined')
{
Blog = {
Posts: []
}
}
// ...
Blog.Posts.push(post);
In my Angular 2 app this JavaScript file is being dynamically loaded and the value then accessed like this:
declare var Blog: any;
...
let firstPost = Blog.Posts[0];
This works, I can access data placed by the external JS.
Now I want to keep the JavaScript part as minimal as possible. So I want to move the declaration of Blog and Posts to TypeScript, preferably so that it can be used there in a strongly typed fashion.
So I wish my JavaScript looked like this:
// ...
Blog.Posts.push(post);
Note the missing declaration of Blog. I tried something like this in TypeScript:
declare var Blog: BlogClass; // <- this is probably wrong, can be changed to anything necessary to make it work...
// ...
Blog = new BlogClass();
But apparently its not that easy. My Angular 2 app dies on me with a generic error message. The error is caused by Blog = new BlogClass().
Any hints on how to solve this?
declare means that the thing being declared must be defined somewhere else.
declare var Blog: BlogClass;
does not produce any code in the resulting javascript, so this assignment
Blog = new BlogClass();
fails at runtime because Blog does not exist.
When you remove declare, this line appears in the generated code:
var Blog;
However, it does not necessarily create var Blog in global scope - when you compile typescript code as modules, it will be created inside a module and will be inaccessible to external javascript code, unless you go through the route of exporting it from typescript module and importing that module in your javacsript code.
The simplest (but a bit dirty) way to make sure that an object is created in global scope is to do that explicitly:
(window as any).Blog = new BlogClass();

How to obtain location of the code being executed in Nodejs

Trying to create a logger javascript class, that I add as a require() in other javascript files. One of the functions of this logger should be, that it writes to the console which script is currently running.
They way I thought it would execute , was that I have a path.basename(__Filename) function inside my logger, but how would I go around targeting the filename of the script executing the logger script?
There is no way to know which file the script itself is in as the browser loads all the scripts under the DOM while loading the page.
function xyz(){
console.log(arguments.callee.toString().match(/function ([^\(]+)/)[1]);
}
This should give you the name of the function that's being called as long as the function is declared in function xyz(){} format. In this case xyz.

What is the difference between var bar = require('myModule') and only require('myModule')?

I have seen that in some projects it is used the common
var myModule = require('myModule');
but in some other cases it is used something like :
require('myModule');
what's the difference between those two ?
One assigns the module to a variable, the other only requires it. Both load and run the script.
With require('foo'), you require the module and load the entry point script. This will evaluate any static code in that script when the module loads for the first time. You do not get access to any exports and cannot reference the module later without requiring it again.
The var bar = require('foo') behaves similarly, except it keeps a reference to the exports and allows you to use them later.
The require-without-assign form is often seen when the "module" is actually some other type of resource, such as a CSS file, and require runs some code to load that CSS into the current page. In common JS modules, without any initialization code, the require-without-assign form will pre-load a module but do little else.
Take a module like:
let connection = new ServerConnection();
export default class Connection {
static getConnection() {
return connection;
}
}
The require-without-assign form will load the script, run it, and create the connection. You won't be able to use it, but it will exist.
The require-with-assign form will load, run, create, and provide a reference. You will be able to call bar.getConnection() and get access to the connection.
In the above example, if you use require without assign, you won't have access to the connection and will never be able to close it, which could be a problem.

Meteor and javascript: make functions in one file available to another

I use iron-router with Meteor and I have written a number of functions that I call from the Router.map() which defines all my routes and hooks. The file is getting to be cumbersome to scroll around in and I would like to move my functions to a different file.
The only way I've found to make functions in one file available to those in another file is to define those functions in a script tag inside the head tag. But of course, I'd rather not put them there. I assume there's a straightforward way to do this?
You create the functions the following way?
function myFunction(){
// Your code...
}
This creates a local variable storing your function (all code in each js-file is wrapped in a function!). You must instead store your function in a global variable, which can be done in the following way:
myFunction = function(){
// Your code...
}
Create a folder named "lib" in your project. Then create functions.js in the lib directory and put there all your functions.
See http://docs.meteor.com/#structuringyourapp

Categories