Calling public method within module javascript - javascript

I'm trying to call a public method from within the module pattern.
I'm using the module pattern because it allows for splitting into various different JS files, to make the code more organised.
However when I call the public method, I get a TypeError and also typeof remains undefined.
Please help!! Thanks in advance.
main.js
function MainObject() {
this.notify = function(msg) { console.log(msg); }
}
var connObj = require("./myextobj");
var mainObj = new MainObject();
connObj.connection.handle = mainObj;
console.log(typeof connObj.connection.connect); // undefined
connObj.connection.connect(); // TypeError: Object has no method 'connect'
myextobj.js
module.exports = {
connection: function () {
this.handle = eventhandle;
this.connect = function() {
// connect to server
handle.notify("completed connection....");
}
}
}

It's because you're exporting an object containing connection: function (), which is a constructor function and needs newing-up. Then you can access the this properties attached to that particular instance:
var connection = require("./myextobj").connection; // reference the constructor function
var conn = new connection(); // new-up connection
console.log(typeof conn.connect); // -> function
Edit:
If the only thing exported by myextobj.js is the constructor function, there's no need to wrap it up in a literal object. I.e. you could do:
module.exports = function Connection() {
this.handle = eventhandle;
this.connect = function() {
handle.notify("completed connection....");
}
}
then use like so:
var Connection = require("./myextobj");
Note: .connection is no longer appended to the end to reference the function.

Give this a shot.
var module = {};
module.exports = {
connection: function () {
return {
handle: eventhandle,
connect: function () {
// connect to server
handle.notify("completed connection....");
}
}
}()
}
module.exports.connection.connect()

Related

How to call a method in javascript from a variable?

I found some questions related to my question, but none of the answers solved my problem for some reason.
I want to call a method in javascript dynamically from a variable.
This is my code:
var malt_type;
export function json_handler(type){
malt_type = type;
try {
window[malt_type]();
} catch (e) {
console.log(e);
}
}
function SQL(){
console.log(malt_type);
}
I tried this also, but didn't work either
var malt_type;
export function json_handler(type){
malt_type = type;
try {
var fnName = malt_type + "()";
var fn = new Function(malt_type);
console.log(fn);
fn();
} catch (e) {
console.log(e);
}
}
function SQL(){
console.log(malt_type);
}
In the previous one the console.log(fn); writes this on the DevTools:
ƒ anonymous(
) {
SQL()
}
And the error I catch is like this (SQL is the content of the variable):
ReferenceError: SQL is not defined
at eval (eval at json_handler (json_handler.js:11), <anonymous>:3:1)
at Module.json_handler (json_handler.js:13)
at Show (server.js:39)
at Socket.<anonymous> (server.js:20)
at Socket.emit (events.js:314)
at TCP.<anonymous> (net.js:672)
My reason is that I want to do this is because I want to handle logs and the type of them differently.
Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope. When running them, they will only be able to access their own local variables and global ones, not the ones from the scope in which the Function constructor was created.
https://developer.mozilla.org/.../Function
The above basicaly means the fn function doesn't have access to SQL variable.
You could try it like this:
var malt_type;
export function json_handler(type){
malt_type = type;
// if it exists execute it
functions[type] && functions[type]();
}
const functions = {
SQL: function SQL(){
console.log(malt_type);
}
};
You can do it as illustrated below.
var malt_type;
function json_handler(type){
malt_type = type;
try {
window[malt_type](); //assuming your SQL() function is defined on the `window` object
} catch (e) {
console.log(e);
}
}
function SQL(){
console.log(`${malt_type} function ran.`);
}
json_handler("SQL");

return whole self invoking functions

How can I return the whole object of the self-inv-function without returning every functions manually?
I want to try with the following solution which should normally work, however, it does not work:
var publish = (function() {
var pub = {};
pub.hello = function() {
return "test"
};
return pub;
}());
now "pub" must be callable by subscribe:
var subsribe = (function(pub) {
function hello() {
return pub.hello();
};
}(publish));
I loaded both files in the browser (pub first).
However:
Debugger says: ReferenceError: pub not defined.
I think you want to write them like this:
var publish = (function() {
var pub = {};
pub.hello = function() {
return "test"
};
return pub;
})();
var subsribe = (function(pub) {
function hello() {
return pub.hello();
};
console.log(hello());
})(publish);
However, keeping a global reusable collections of functions can be accomplished in other ways, more elegantly maybe :) (separate file with export, singleton decorated with those methods)
You can't.
There's no mechanism in JS to get a list of variables in the current scope.
Even if you could, it probably wouldn't be a good idea as there would be no way to distinguish between public and private variables.
There is no such a mechanism but you can do something like this:
var publish = (function() {
const me = this;
let publicMethods = ['hello', 'bye'];
// private
function _hello() {
return "test";
};
function _bye() {
return "end test";
};
publicMethods.forEach((methodName) => {
let privateMethod = eval('_' + methodName);
Object.defineProperty(me, methodName, {
get: function() {
return privateMethod;
}
});
});
return this;
}());
console.log(publish.hello);
console.log(publish.bye);
console.log(publish.hello());
console.log(publish.bye());

How to invoke javascript OOPS based class in another javascript

I have a javascript class called "LayoutProcessor".js ,defined as follow:
define('layoutProcessor', ['jquery'], function($) {
"use strict";
function LayoutProcessor() {
return (this);
}
LayoutProcessor.prototype.process = function() {
console.log('inside process');
};
LayoutProcessor.prototype.responseHandler = function() {
console.log('inside responseHandler');
};
return new LayoutProcessor();
});
I am trying to access the method "process" in another javascript class called "test.js", which is defined as follow:
test.js
require(['LayoutProcessor.js','jquery'], function(layoutProcessor,$) {
$(document).ready(function(){
var response = new LayoutProcessor().process();
});
})
But I am getting a type error:
new LayoutProcessor() is not a constructor.
As per the implementation by OP, it should be
var response = layoutProcessor.process();
not
var response = new LayoutProcessor().process();
Please refer the fiddle
The error message is appropriate, as its not a constructor but an object.
new LayoutProcessor() is not a constructor.
LayoutProcessor.js returns an Object.
return new LayoutProcessor();
There are few things going on with those code.
The way it is current written, LayoutProcessor module returns a constructed object, not a constructor to call.
To call it you would use:
var response = layoutProcessor.process();
However, this makes a singleton, which I doubt is what you mean.
In a singleton, there will only be one instance if layoutProcessor, since that instance is created by the LayoutProcessor module.
I believe the code that you mean would be more like this, where you create a new instance of the object for everyone that needs it:
layoutProcessor
define('layoutProcessor', ['jquery'],
function($) {
"use strict";
//----------------------------------------
/**
* constructor
*/
function LayoutProcessor() {
return (this);
}
LayoutProcessor.prototype.process = function() {
console.log('inside process');
};
LayoutProcessor.prototype.responseHandler = function() {
console.log('inside responseHandler');
};
// Note: Return a FUNCTION reference to be called later.
return LayoutProcessor;
}
);
test.js
require(['LayoutProcessor.js', 'jquery'],
function(LocalLayoutProcessor, $) {
$(document).ready(function() {
var response = new LocalLayoutProcessor().process();
});
}
)
Only issue is return statement. it should be
return LayoutProcessor;

How to Properly Access Class Properties in Javascript

I have this class definition:
$.note = function() {}
$.note.prototype = {
init: function(note) {
this.note = note;
this.ctrl = document.getElementById(note);
},
// I have these getter functions because I was getting errors using
// myObject.note or myObject.ctrl
getNote: function() {
return this.note;
},
getCtrl: function() {
return this.ctrl;
}
}
I created a new object with this class like this:
var note = new $.note('C');
Which I can access in my console like this:
But when I try and access note.getNote(), I get undefined as the response:
Am I going about accessing these properties incorrectly? I've tried using just note.note or note.ctrl, and I get the same thing...
Nothing's going to call that "init" function if you don't.
$.note = function(note) { this.init(note); }
Some frameworks provide an object system that uses constructor helper functions like that, but plain JavaScript doesn't.
Try this:
$.note = function(note) { this.note = note;}
or you should call init function:
var note = new $.note();
note.init('C');

Is it possible to append functions to a JS class that have access to the class's private variables?

I have an existing class I need to convert so I can append functions like my_class.prototype.my_funcs.afucntion = function(){ alert(private_var);} after the main object definition. What's the best/easiest method for converting an existing class to use this method? Currently I have a JavaScript object constructed like this:
var my_class = function (){
var private_var = '';
var private_int = 0
var private_var2 = '';
[...]
var private_func1 = function(id) {
return document.getElementById(id);
};
var private_func2 = function(id) {
alert(id);
};
return{
public_func1: function(){
},
my_funcs: {
do_this: function{
},
do_that: function(){
}
}
}
}();
Unfortunately, currently, I need to dynamically add functions and methods to this object with PHP based on user selected settings, there could be no functions added or 50. This is making adding features very complicated because to add a my_class.my_funcs.afunction(); function, I have to add a PHP call inside the JS file so it can access the private variables, and it just makes everything so messy.
I want to be able to use the prototype method so I can clean out all of the PHP calls inside the main JS file.
Try declaring your "Class" like this:
var MyClass = function () {
// Private variables and functions
var privateVar = '',
privateNum = 0,
privateVar2 = '',
privateFn = function (arg) {
return arg + privateNum;
};
// Public variables and functions
this.publicVar = '';
this.publicNum = 0;
this.publicVar2 = '';
this.publicFn = function () {
return 'foo';
};
this.publicObject = {
'property': 'value',
'fn': function () {
return 'bar';
}
};
};
You can augment this object by adding properties to its prototype (but they won't be accessible unless you create an instance of this class)
MyClass.prototype.aFunction = function (arg1, arg2) {
return arg1 + arg2 + this.publicNum;
// Has access to public members of the current instance
};
Helpful?
Edit: Make sure you create an instance of MyClass or nothing will work properly.
// Correct
var instance = new MyClass();
instance.publicFn(); //-> 'foo'
// Incorrect
MyClass.publicFn(); //-> TypeError
Okay, so the way you're constructing a class is different than what I usually do, but I was able to get the below working:
var my_class = function() {
var fn = function() {
this.do_this = function() { alert("do this"); }
this.do_that = function() { alert("do that"); }
}
return {
public_func1: function() { alert("public func1"); },
fn: fn,
my_funcs: new fn()
}
}
var instance = new my_class();
instance.fn.prototype.do_something_else = function() {
alert("doing something else");
}
instance.my_funcs.do_something_else();
As to what's happening [Edited]:
I changed your my_funcs object to a private method 'fn'
I passed a reference to it to a similar name 'fn' in the return object instance so that you can prototype it.
I made my_funcs an instance of the private member fn so that it will be able to execute all of the fn methods
Hope it helps, - Kevin
Maybe I'm missing what it is you're trying to do, but can't you just assign the prototype to the instance once you create it? So, first create your prototype object:
proto = function(){
var proto_func = function() {
return 'new proto func';
};
return {proto_func: proto_func};
}();
Then use it:
instance = new my_class();
instance.prototype = proto;
alert(instance.prototype.proto_func());

Categories

Resources