Browserify/JavaScript, otherjs.myfunction is not a function() - javascript

I'm trying to make something in JS and using browserify to use other JS files in my main code. I know I have node and browserify installed correctly because I can enter "browserify example.js -o bundle.js" in the terminal and run his code just fine.
I finally just added my function (soundoff()) to his system.js code below and tried calling it the same way he called the functions in this file in the second code snippet...
module.exports = (function (){
var _final = "",
DEFAULT_STEP = 15,
DEFAULT_TURN = Math.PI / 4;
/* Initializes an L-System using the supplied
* axiom, rules, and number of iterations
* params:
* - axiom: the starting string
* - rules: the array of rules as string -> string
* key/value pairs (i.e. ["key", "value"]
* - iterations: the number of iterations to carry out
*/
function lsystem(axiom, rules, iterations) {
_final = axiom;
for(var i = 0; i < iterations; i++) {
_final = apply(_final, rules);
}
return _final;
}
function soundoff(done) {
return done;
}
You see below here I'm calling it the same way he's calling other functions from the ls reference/function/module but I still get "Uncaught TypeError: ls.soundoff is not a function"
window.onload = function() {
var ls = require('./lsystem.js');
var wonk = ls.soundoff("wonk!");
// Set up the algae demo
var aIter = document.getElementById("algae-iterations"),
aOut = document.getElementById("algae-output");
aOut.value = ls.algae(0);
aIter.onchange = function() {
aOut.value = ls.algae(aIter.value);
}
Without calling this function it works perfectly. Those aren't the whole code files but I know everything else if fine since they work, I just can't figure out why I can't have a function I put in like that and call it...
Thanks in advance for the help! :)

That wont work. Because soundoff is a function within lsystem function, which means soundoff is not accessible as a property.
If you can change your lsystem to export an Object and do this, it will work.
module.exports = {
soundoff : function(done){
return done;
}
}
Edit :
Method 1:
file1.js
module.exports = (function func(){
return {
soundoff : function(done){
return done;
}
}
});
file2.js
var func = require('file1');
var obj = func();
obj.soundoff('wonk');
Method 2.
file1.js
module.exports = {
soundoff : function(done){
return done;
}
}
file2.js
var obj = require('file1');
obj.soundoff('wonk');
Method: 3
There are other dirty ways where you could, use the this property in conjunction with Function.prototype.call, but I would advise you not to go for it. Do not use it, like, ever. Highly volatile.
file1.js
module.exports = (function func(){
this.soundoff = function(done){
return done;
}
});
file2.js
var func = require('file1');
func.call(func);
func.soundoff('wonk');

Related

How exactly works the require of javascript files with mod_v8 in freeswitch scripts?

I'm really stuck here. While the require of modules in mod_lua seems to work right similiar with the lua interpretor, the require() in mod_v8 seems to "include" the whole scripts. I haven't found a way to make works the import only the modules (not node modules) I need in the script.
For example, in the script I've some like below:
//core/dtmf_1.js
const a = (arg) => { return arg * 2 }
const b = (arg) => { return arg / 2 }
//I get an error DONT WORKS
exports.a = a
exports.b = b
The example below don't worked to me too, but does not throw an error.
//core/dtmf_2.js
export function a = (arg) => { return arg * 2 }
export function b = (arg) => { return arg / 2 }
Otherwise, when I call
//ivr.js
import a from 'core/dtmf_2.js'
I get an error in 'import'
But if I simply do:
//core/dtmf_3.js
const function a = (arg) => { return arg * 2 }
const function b = (arg) => { return arg / 2 }
//ivr.js
require('core/dtmf_3.js')
console.log(b(30)) <-- WORKS! Outputs 15
I was wondering if there's some setting in conf of mod_v8 to allow the import of modules. I want to do that because I have diferent methods predefined in my library, but I rarely use more than one by service.
Thanks in advice.
FreeSwitch uses V8, not Node.js so you wont get require and export functions. For including JavaScript scripts you can use FreeSwitch include or require keywords - which are the same thing. Include will include entire script so you can't do something like example below because you are loading math.js twice so exception will occur: SyntaxError: Identifier 'pi' has already been declared (near: "const pi = 3.14;")
math.js
const pi = 3.14;
function circleArea(radius){
return radius * radius * pi;
}
function sum(a, b){
return a + b;
}
circle.js
include('/etc/freeswitch/test/math.js');
function getArea(radius){
return circleArea(radius);
}
main.js
include('/etc/freeswitch/test/circle.js');
include('/etc/freeswitch/test/math.js');
//math.js
log( sum(5,10) );
//circle.js
log( getArea(10) );
Include function into variable
include implementation allows you to "copy-paste" code from script into script which calls include in first place so you can utilize that to load code into variables. For example:
math.js
(a, b) => {
return a + b;
}
main.js
const sum = include('/etc/freeswitch/test/math.js');
//logs 15
log( sum(5, 10) );
Include self-invoking function into variable
Now you won't get problems with loading same script into global scope. We can get this to another level with use of self-invoking functions.
math.js
(() => {
const pi = 3.14;
function circleArea(radius){
return radius * radius * pi;
}
function sum(a, b){
return a + b;
}
return { circleArea, sum };
})();
main.js
const math = include('/etc/freeswitch/test/math.js');
const { sum, circleArea } = include('/etc/freeswitch/test/math.js');
//with module
log( math.circleArea(5) ); // logs 78.5
log( math.sum(5, 10) ); // logs 15
//direct call
log( circleArea(5) ); // logs 78.5
log( sum(5, 10) ); // logs 15
But every time you want to load math.js it will act as it's own module and will load multiple times, not acting like Node.js module. For example:
FreeSwitch
math.js
(() => {
log("Math loaded...");
})();
main.js
const math1 = include('/etc/freeswitch/test/math.js');
const math2 = include('/etc/freeswitch/test/math.js');
This prints "Math loaded..." twice.
Node.js
math.js
(() => {
console.log("Math loaded...");
})();
main.js
const math1 = require('./math.js');
const math2 = require('./math.js');
This prints "Math loaded..." once.
Include self-invoking function into variable only once
From here you can write your own include script (it is still bad approach, but should work). Something like this:
include.js
if (typeof _include === 'undefined') {
var _loadedScripts = {};
function _include(script){
if (!_loadedScripts.hasOwnProperty(script)){
_loadedScripts[script] = include(script);
}
return _loadedScripts[script];
}
}
And then you can write your modules like before:
math.js
(() => {
log("Math loaded...");
var pi = 3.14;
return { pi };
})();
And when you want to include scripts:
main.js
include('/etc/freeswitch/include.js');
const math1 = _include('/etc/freeswitch/test/math.js');
const math2 = _include('/etc/freeswitch/test/math.js');
math1.pi = 10;
math2.pi = 20;
log(math1.pi);
log(math2.pi);
This will produce:
Math loaded...
20
20
[EDIT]
Include.js is the only script that is not loaded as "module" so it will be loaded multiple times. You can prevent this by replacing default include function with your own and instead of include you use require.
include.js
if (typeof _include === 'undefined') {
var _loadedScripts = {};
function _include(script){
if (!_loadedScripts.hasOwnProperty(script)){
_loadedScripts[script] = require(script);
}
return _loadedScripts[script];
}
include = () => { };
}
Now if Include.js is already included, everytime you call include("include.js") it won't load again.

Is is bad practice to pass an empty callback in Javascript?

I have a long running function that I don't really care about handling properly. Is it bad practice to just hand it off to the event loop along with an empty callback and move on. Something like this:
var takeSomeTime = function(callback) {
var count = 0,
max = 1000,
interval;
interval = setInterval(function() {
count++;
if (count === max) {
interval.clearInterval();
return callback();
}
}, 1000);
};
var go = function(callback) {
// do some stuff
takeSomeTime(function(err) {
if (err) {
console.error(err)
}
// take all the time you need
// I'm moving on to to do other things.
});
return callback();
};
go(function(){
// all done...
});
I don't know how your question is related to memory leaks, but one could certainly think of useful applications of passing empty function around in general. You basically could pass an empty function to third party code, that expects a function and doesn't check if it actually got one. Just like in your example, or this small logging library:
// Javascript enum pattern, snatched from TypeScript
var LogLevel;
(function (LogLevel) {
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
LogLevel[LogLevel["WARN"] = 1] = "WARN";
LogLevel[LogLevel["ERROR"] = 2] = "ERROR";
LogLevel[LogLevel["FATAL"] = 3] = "FATAL";
})(LogLevel || (LogLevel = {}));
// end enum pattern
var noLog = function() {}; // The empty callback
function getLogger(level) {
var result = {
debug: noLog,
warn: noLog,
error: noLog
};
switch(level) {
case LogLevel.DEBUG:
result.debug = console.debug.bind(console);
case LogLevel.WARN:
result.warn = console.warn.bind(console);
case LogLevel.ERROR:
result.error = console.error.bind(console);
}
return result;
}
var log1 = LogFactory.getLogger(LogLevel.DEBUG);
var log2 = LogFactory.getLogger(LogLevel.ERROR);
log1.debug('debug test');// calls console.debug and actually displays the
// the correct place in the code from where it was called.
log2.debug('debug test');// calls noLog
log2.error('error test');// calls console.error
You basically return the empty function noLog back to the consumer of our library in order to disable logging for a particular log level, yet it can be called with any number of arguments without raising errors.

How do we return function using module.exports in nodeJS?

How do we return function using module.exports in nodeJS?
file_1 book.js
module.exports = function() {
var points = 0;
return {
rate: function(value) {
points = value;
},
get: function() {
return points;
}
}
}
book.js is root file. We create two different instances but can not get the methods of root to script.js file.
file_2 main.js
var bA = require('./book.js');
var bB = require('./book.js');
bB.rate(10);
bB.get();
Output => can not find rate and get method.
Because the function returns an object with references to the rate and get functions, you need to execute it with a () on require like so:
var book = require('./book.js')();
book.rate(10);
book.get();
You're returning a function which returns an object.
Call the function and get the object
/*file_2 main.js*/
var bA = require('./book.js')();
var bB = require('./book.js')();
bB.rate(10);
bB.get();
Just in case if someone's facing same problem as me
I had something issue with my code. Lately realised I was making some API call and so return returned an object before fetching the value from API endpoint
I added async in front of function call and it worked!
var util=require('./app/Utils')
const url=await util.getInfo();
You can also provide a name to your anonymous export function as
module.exports.myfun = function() {
var points = 0;
return {
rate: function(value) {
points = value;
},
get: function() {
return points;
}
} }
Then use the function in another file as
var inc = require('./comp.js');
var mod = inc.myfun();
mod.rate(10);
console.log(mod.get());
In this way you don't need to have '()' at the time of required, though that option can also be used

javascript revealing module pattern extension suggestion

I would like to achieve module pattern in JS. I followed some posts in google and starting writing my own.
here is what I would like to achive
mns - will be the name space for my lib
math - will be one of the sub-module in mns
and I want all these modules in separate files.
here is mns.js file code (it is just for namespace no functions in it)
var mns = (function () {
return {};
})();
here is math.js code(i want this as a submodule for mns)
var submodule = (function (mns) {
var math = (function(){
var counter = 0;
var incrementCounter = function () {
return counter++;
}
var resetCounter = function () {
alert( "counter value prior to reset: " + counter );
counter = 0;
}
})();
mns.math = math;
return mns;
})(mns || {});
I am expecting application.js will call like below
mns.math.incrementCounter();
mns.math.resetCounter();
Right now, I am getting Cannot read property of undefined error when calling incrementCounter & resetCounter.
Please guide me in this.
All is looking good, except for the math module:
var math = (function(){
var counter = 0;
var incrementCounter = function () {
return counter++;
}
var resetCounter = function () {
alert( "counter value prior to reset: " + counter );
counter = 0;
}
})();
In order to use incrementCounter and resetCounter you have to return them in an object (So that math will be set to something).
Something like this should work:
var math = (function(){
var counter = 0;
var incrementCounter = function () {
return counter++;
}
var resetCounter = function () {
alert( "counter value prior to reset: " + counter );
counter = 0;
}
return {
incrememtCounter: incrememtCounter,
resetCounter: resetCounter
}
})();
Following is the way, I achieved it. Please suggest better approach
mns.js file
var mns = {};
math.js file
mns.math = (function(){
var counter = 0;
var incrementCounter = function () {
return counter++;
};
var resetCounter = function () {
alert( "counter value prior to reset: " + counter );
counter = 0;
};
return{
incrementCounter : incrementCounter,
resetCounter : resetCounter
}
})();
Rather than dealing with the semantics of creating closures, I recommend using Browserify to handle your module patterns for you. This allows you to separate everything into multiple files, as well as use the file name as an identifier for your modules. It helps to reduce the amount of boilerplate and makes the code easier to understand. It also mimics NodeJS modular CommonJS syntax which is nice as well.
I think what you're looking for is this...
// mns.js
(function(window) {
var mns = function() {
// your private code here...
return {
// public module interface...
}
}();
window.mns = mns;
})(window);
// math.js
(function(mns) {
var math = function() {
// your private code here...
return {
// public module interface...
}
}();
mns.math = math;
})(window.mns);
In your HTML page, you will need to load mns file first, and then math file. Or maybe you could use some tool to connect these files and load a unique minified file like mns.min.js. For me Gulp.js is a magnificent tool for that propose. Use some concat operation of the Gulp.js to join the file in an specific order, like I said.
If you want a real-world example, see this:
https://github.com/viniciusknob/queiroz.js/blob/master/dist/queiroz.js

Closure compiler export Typescript classes and functions

I am trying to use closure compiler advanced mode on typescript generated classes with no success. Is there anyone who has accomplished such things.
Typescript Class
class TestData {
BlogName: string;
CacheTimeOut: number;
CopyrightHolder: string;
constructor(blogName: string, cacheTimeOut: number, copyrightHolder: string) {
this.BlogName = blogName;
this.CacheTimeOut = cacheTimeOut;
this.CopyrightHolder = copyrightHolder;
}
addBlog(value: string): boolean {
console.log('add blog');
return true;
}
validate(): boolean {
console.log('all valid');
return true
}
}
var myTestData = new TestData("name",22,"cpyright");
Generated Code
var TestData = (function () {
function TestData(blogName, cacheTimeOut, copyrightHolder) {
this.BlogName = blogName;
this.CacheTimeOut = cacheTimeOut;
this.CopyrightHolder = copyrightHolder;
}
TestData.prototype.addBlog = function (value) {
console.log('add blog');
return true;
};
TestData.prototype.validate = function () {
console.log('all valid');
return true;
};
return TestData;
})();var myTestData = new TestData();
This compiles into
new function() {};
I understand I should provide exports, so I added
window['TestData'] = TestData;
window['TestData'].prototype['addBlog'] = TestData.prototype.addBlog
window['TestData'].prototype['validate'] = TestData.prototype.validate
my output from closure compiler advanced compilation is
var a = function() {
function b() {
}
b.prototype.a = function() {
console.log("add blog");
return !0;
};
b.prototype.b = function() {
console.log("all valid");
return !0;
};
return b;
}();
window.TestData = a;
window.TestData.prototype.addBlog = a.prototype.a;
window.TestData.prototype.validate = a.prototype.b;
new a;
If you see there is still no constructor code that is left. This gets worse when we add this inside a module.
I also tried to use the #export of google closure wiht no success
I see couple of pluggins which can generate closure compiler annotations based on typescript, but those also doesnt generate proper code.
Thirdparty closure annotations generator
I ran a very basic test of this. Perhaps you changed your code and haven't re-tried.
If you compile the TypeScript in your question, it should result in the following JavaScript:
var TestData = (function () {
function TestData(blogName, cacheTimeOut, copyrightHolder) {
this.BlogName = blogName;
this.CacheTimeOut = cacheTimeOut;
this.CopyrightHolder = copyrightHolder;
}
TestData.prototype.addBlog = function (value) {
console.log('add blog');
return true;
};
TestData.prototype.validate = function () {
console.log('all valid');
return true;
};
return TestData;
})();
var myTestData = new TestData("name", 22, "cpyright");
In particular, the last line passes arguments to the TestData constructor.
A quick run of this results in (white-space is mine) using #compilation_level SIMPLE_OPTIMIZATIONS:
var TestData=function(){
function a(a,b,c){
this.BlogName=a;this.CacheTimeOut=b;this.CopyrightHolder=c
}
a.prototype.addBlog=function(a){console.log("add blog");return!0};
a.prototype.validate=function(){
console.log("all valid");return!0
};
return a
}(),myTestData=new TestData("name",22,"cpyright");
If you use advanced optimizations on partial code, it will be too aggressive. You need to supply all of your code for the Closure compiler to understand what really isn't used.
If your example represents all of your code, you'll notice that the constructor along with all three properties (BlogName, CacheTimeOut, and CopyrightHolder) are genuinely never used, so can be removed without affecting the behaviour of the program.
Answer: optimized noops are - wait for it - noops :)
Explanation:
If you use your gen code here http://www.closure-compiler.appspot.com/home
with ADVANCED_OPTIMIZATIONS it produces:
new function(){};
if you add myTestData.addBlog("test"); it produces:
(new (function(){function a(){}a.prototype.a=function(){console.log("add blog")};return a}())).a();

Categories

Resources