Invoking JavaScript "new" from CoffeeScript - javascript

I am trying to reuse a JavaScript library (sim.js) in CoffeeScript code. In an example that comes with sim.js, there are 3 files, "sim-0.26.js", "buffet_restaurant.js", and "buffet_restaurant.html" wired together like this (I've eliminated some parameters to simplify):
Inside of "buffet_restaurant.html", there is
<script type="text/javascript" src="./buffet_restaurant_files/sim-0.26.js"></script>
<script type="text/javascript" src="./buffet_restaurant_files/buffet_restaurant.js"></script>
<script type="text/javascript">
$(function () {
$("#run_simulation").click(function () {
var results = buffetRestaurantSimulation();
...
where buffetRestaurantSimulation is a function inside of buffet_restaurant.js. The code in buffet_restaurant.js starts off like this:
function buffetRestaurantSimulation()
{
var sim = new Sim();
...
where Sim is defined in sim-0.26.js, like this:
function Sim(){...};
This example runs fine. I want to reuse "Sim" in a CoffeeScript file in node.js. So I try this (invoked from jasmine-node):
sjs = require "./sim-0.26.js"
mysim = new sjs.Sim()
where sim-0.26.js is in the same directory as testsim.spec.coffee, the file containing this code. When I invoke this using:
jasmine-node --coffee ./testsim.spec.coffee
I get this:
mysim = new sjs.Sim();
^
TypeError: undefined is not a function
I suspect I am doing a ton of things wrong. I'm pretty new to all this.
Any ideas?

Unless Sim is added to exports it will not be available when required - see the docs on modules for more information on the way Node.js modules need to be written.
If this needs to work in both the browser and in node, then simply add this to the code for sim.js:
var root = typeof exports === "object" ? exports : window;
root.Sim = Sim;

Related

Best way to share an instance of a module that is inside a closure [duplicate]

If I want to span my JavaScript project across multiple source files, but have each file have access to the same private variable, how would one do that?
For example, if I have the following code:
APP = (function () {
var _secret = {},
app = {};
// Application part 01:
app.part01 = (function () { /* function that uses _secret */ }());
// Application part 02:
app.part02 = (function () { /* function that uses _secret */ }());
//
return app;
}());
How do I put app.part01 and app.part02 in seperate files, but still have access to _secret?
I don't want to pass it as an argument. That's just giving the secret away, as app.part01() could be replaced by any other function.
Maybe I am asking the impossible, but your suggestions might lead me in the right way.
I want to work with multiple files, but I don't know how. Copying and pasting everything inside a single function each time before testing is not something I want to do.
How do I put app.part01 and app.part02 in seperate files, but still have access to _secret?
That's impossible indeed. Script files are executed in the global scope, and don't have any special privileges. All variables that they will be able to access are just as accessible to all other scripts.
Copying and pasting everything inside a single function each time before testing is not something I want to do
What you are looking for is an automated build script. You will be able to configure it so that it bundles your files together, and wraps them in an IEFE in whose scope they will be able to share their private state. The most simple example:
#!/bin/sh
echo "APP = (function () {
var _secret = {},
app = {};" > app.js
cat app.part01.js >> app.js
cat app.part02.js >> app.js
echo " return app;
}());" >> app.js
The only way that you can share _secret is attaching it to the application object and then application object to the window object. Here is an example.
// FIRST JS FILE...
var application; // will be attached to window
(function(app) {
app.secret = "blah!"; // will be attached to application
})(application || (application = {}));
// ANOTHER JS FILE
var application;
(function(app) {
app.method1 = function(){ console.log(app.secret); }; // will be attached to application;
})(application || (application = {}));
console.log(application.method1()); // will display 'blah!' on the console
Working example on jsbin
One way I was able to accomplish this was to create a JS file that contained the global object.
// Define a global object to contain all environment and security variables
var envGlobalObj = {
appDatabase: process.env.YCAPPDATABASEURL,
sessionDatabase: process.env.YCSESSIONDATABASEURL,
secretPhrase: process.env.YCSECRETPHRASE,
appEmailAddress: process.env.YCAPPEMAILADDRESS,
appEmailPassword: process.env.YCAPPEMAILPASSWORD
}
module.exports = envGlobalObj
Then in the files I wish to reference this object, I added a require statement.
var envGlobalObj = require("./envGlobalObj.js");
This allowed me to centralize the environment and secrect variables.

JavaScript - Instantiate from require

I have a Node program. This program is importing some code. That code looks like the following:
sample.js
function SampleModel() {
this.name = 'Test';
}
module.exports = SampleModel;
I am using SampleModel in another file. Currently, I am successfully using it like this:
another.js
var SampleModel = require('./sampleModel');
var model = new SampleModel();
For the purpose of education, is there a way to condense these two lines down to a single line of JavaScript? If so, how?
Thank you!
Like this:
var model = new (require('./sampleModel'))();
It's quite common to access the required module directly in the import line, but you'll mostly see property access (like require('events').EventEmitter).

How to use function declared in different JS file using jQuery getScript?

I have two JS files. One is called common.js and it use $.getScript to include other file with my js code. Part of including looks like this:
jQuery.getScript(js_path + "table.js", function(){
generateTable(chartData, dataTypes);
});
This file (common.js) also contains function compare(a, b).
Now, the second one (table.js) has declared different function which uses the compare function from the first file. Something like this:
function someName() {
var a = 2,
b = 5;
var test = compare(a, b);
return test;
}
When I run the code it gives me:
Uncaught ReferenceError: compare is not defined
How can I use function from the first file.
jQuery.getScript first fetches the JS file from the server, then executes it. If you want to work with global functions (as it seems) you need to pay attention to the following:
Your compare function must be declared before the table.js file is executed.
The compare function must be declared on the global namespace of table.js.
Sorry but without more info this is all you can get.
If your main file, as something like:
(function() {
function compare(){...}
}());
Then the compare function is not declared in the global namespace.
did you check the order of imports? The file with 'compare' method should be first. It should solve the problem.
What I would suggest is to skip getScript if it's just for separating the code.
<script src="common.js"></script>
<script src="table.js"></script>
<script src="app.js"></script>
Where common functions go into common, your table stuff goes into table. This way you get the ordering right. This also clears out the circular dependency one might see a hint of if table depends on common that depends on table by extracting all but the 'common' parts into some form of 'app'.

EmberJS, jQuery UI, and Grunt.

I am integrating Emberjs and jquery ui. using the methods mentioned in http://www.lukemelia.com/blog/archives/2012/03/10/using-ember-js-with-jquery-ui/
Everything thing seems to be working ok.
The problem is following:
When I have
JQ = {};
to declare a new namespace I faced with this error (although it works fine on the browser)
JQ is not defined
when I declare the same variable as
var JQ = {};
Grunt shows no errors but it stops working in the browser.
I looked into the combined code in the browsers it is like the following
function(){
var JQ = {};
}
....rest of the code
so I am sure it is declared but the browser don't mange to see it.
So I can't find out the problem? nor the solution
Best,
Mohammad
if you want to make JQ global..declare it as window.JQ = {}
i think issue may be just linting....add JQ to the globals...
In orderto make sure jshint doesnt throw error..add JQ to the global list in .jshintrc file
When you use var JQ = {}; and the result is
function(){
var JQ = {};
}
your variable is defined only in the scope of that function, which means that you can't use it outside of that closure. So, when you use JQ = {}; your compiled file should contain:
function(){
JQ = {};
}
which defines the variable in the global namespace. But you said that you got JQ is not defined, so I could suggest to check if you don't use the variable before its definition.

Global JavaScript namespace and Mocha

I have been tasked with implementing Mocha tests for some JavaScript that already exists on a large website. This website has a global namespace object to hold all of it's functions and common vars, as well as a per page set within the same object, and I have attempted to use Mocha to recognise this but I cant seem to.
For example:
//global namespace declaration in the common.js file
var ns = {};
ns.commonValue = 1;
ns.commonFunc = function () {};
//extension of the namespace on an individual page
ns.thisPage = {};
ns.thisPage.pageVal = 1;
When testing the individual page JavaScript, ns is undefined.
Any help would be good.
Thanks in advance
Given your files are named
common.js
page.js
Then you should have
<script src="common.js"></script>
<script src="page.js"></script>
<script src="test.page.js"></script>
load page without mocha, and look at what inspector says, then correct, then add mocha

Categories

Resources