Calling Functions in Different JavaScript Files With Node.js - javascript

I have a Node.js library file that is required by my Node.js application file, exporting a function.
In the application file I am calling the exported function, passing it some parameters, and it is working fine.
In one of the parameters, I would like to send the name of a function that is declared in the application file; this is so that the parameters can be JSONified. However, the code in the library file cannot find the function by name, because it exists in another file (the application one).
I know I can get over this by passing a pointer to the function, instead of its name, but because of serialization (functions cannot be serialized), I would like to pass the name.
I cannot just export the function from the application file and import it in the library file because that would be a circular reference, and, of course, the library file does not need to know about the application one.
What is the recommended pattern for dealing with this kind of situations?

The recommended pattern is still to probably pass a function object - why does your function get serialized when you pass a reference to it?
A really easy alternative would be to just define your function in the global scope but this pollutes the global scope and goes against the really awesome encapsulated way we write nodejs code:
global.yourCallback = function() { ... }
and now the string yourCallback will work.

You could register the function with your library in advance, in a kind of configuration-stage or when loading/defining the function:
var mylib = require('./mylib')
function myfunc(){
// ...
}
mylib.register('myfunc', myfunc);
Assuming the registration is done at start-up then the library and consumers of the library would be able to refer to it as 'myfunc'.
Other libraries/frameworks such as AngularJS do similar things, e.g.:
angularModule.controller('MyController', function(){/*...*/});

Related

Adding object prototypes dynamically

Ordinarily in standards JavaScript projects I have a series of Date/Array/String.prototype functions I used regularly and declare using a utilities file.
Trying to use a similar method in Google Apps Script, I'm setting up a library but object prototypes don't carry across when the library is loaded, and aren't recognised when they'd declared in the library and called from a function in the library.
E.g. In library file:
Array.prototype.test = function(){
console.log('test prototype');
}
In file library is used, calling [].test() would error as undefined. The same calling a function in the library with this in it.

Expressjs - global objects

I have an app written using express with connections to db, logger and other long living objects that requires to be open and accessed by multiple js files.
What are some of the techniques I could use to make the object "global" with minimal overhead/maintanence?
Thanks
In my opinion, you could put it in a foo.js file and use require('foo.js') to load it. This object is created only one according to This question
Define like this
//global.js
module.export = function(){
//define your global object and function here.
}
and call
require('global.js') in your script where you want

Extend JavaScript Class from separate file

I'm sorry to ask quite a dim question as I'm very new to OOP in JavaScript.
I'm trying to use John Resig's Simple JavaScript Inheritance method, and ideally I'd like to store this within say utils.js, and then use it (using Class.extend), throughout the range of script files that my project uses. Is this possible? I've noticed that if I create a subclass from within my utils.js file, I can then create a new instance of that class from a different script, so that makes me think it might be possible. Does it have something to do with the method being wrapped in an immediately-invoked function expression?
Sure it's possible, just load the util.js file before the rest. ALthough if I were you (seems like you're starting to have several different files in your project) I'd check out http://requirejs.org/ or some other AMD library to break up your project in modules.
Yes, this is possible only thing is you have to include Utils.js file before calling Class.extend, so that browser should be able to find the base class.
Browser works like an interpreter, it loads scripts once it finds the script tag
Does it have something to do with the method being wrapped in an immediately-invoked function expression?
Yes, in the moment in which the utils.js script is loaded, the method executes and returns the object Class to the global scope. From then on, the object can be used in all other files.

Creating a "controller" script for Node.js

I'm creating a program in Node.js. I'm pretty new to programming anything other than small javascript functions for websites so please bear with me if my terminology/ideas are totally wrong.
I originally had the entire program in one giant (~500 line) script file. Several people suggested I split it up into separate classes, where each class only has one 'job' to complete. I like this idea as it has helped me really streamline my code and make it more modular and manageable.
My issue is: How do I access these classes from a central file?
For instance, pretend I have 3 classes, in 3 separate javascript files, all containing 3 functions each. I want to access and pass data to/from all of these from one central "controller" script. What's the best way to do this? Can I just require it into a variable, then access the script's functions like so?
var class1 = require('./class1.js');
class1.function1(); // call the first function contained in class1.js
Is such a thing even possible? Again, totally new to this.
NodeJS supports CommonJS modules. A CommonJS module provides three global variables: module, exports and require.
You can export your API by adding to the exports object and require these files just like other node modules (add ./ to indicate that it is relative to the current file), assign it to a variable and access the values you added to that files exports object:
// first-module.js
exports.hello = 'world';
exports.num = 23;
// main.js
var first = require('./first-module');
console.log(first.hello);
console.log(first.num);
You need to add functions to the exports object in class1.js.
require("./class1") will return this object.

How to correctly modularize a node.js project?

I'm creating a node.js project following the class constructor pattern:
function my_class(x,y){
this.x = x;
this.y = y;
}
The starting point of the project is the main.js file. Any class of the project must be able to access global objects (such as "world" and "socket") which are defined on main.js. I found 4 options:
I define my classes inside main.js. They'll have access to main.js's globals for being on it's closure, but main.js will become bloated.
I move the class to another file such as my_class.js and require() it. This doesn't work because my_class's instances will lose the closure context and no longer be able to access main.js's globals.
I move the class to another file and manually inject dependencies to it's constructor (ex: my_class(world,socket)). The problem is, code becomes much more complicated and weird semantics such as "my_instance.world" pop on the source, which is nonsense because "world" is not property of my_class.
I move the class to another file and require it using my_class = eval(fs.readFileSync(()) instead of require. This works just fine as my_class gets main.js's closure context, and is the solution I'm using, but seems hacky.
Which is the right way to modularize such node.js project?
If I understood you correctly the possible solution:
main.js:
(function(){
var global = "test"; // this you wanna have as a closure
var my_class = require('./my_class')(global);
my_class.go();
})();
my_class.js:
module.exports = function(global){
return {
go: function(){
console.log(global);
}
};
};
So it's similar to your 3. option
Your problem seems tricky because you have a circular dependency: main.js depends on the functionality of my_class and my_class depends on the data of main.js.
By putting the data of main.js into the global object you resolve the circular dependency:
main.js depends on the functionality of my_class.js
main.js depends on the data in the global object
my_class.js depends on the data in the global object
Now, to get rid of putting the data into the global object, implement a third module in let us say data.js. Then you require the sources like this:
main.js requires data.js
main.js requires my_class.js
my_class.js requires data.js
Since modules in node.js are singletons both main.js and my_class.js will get the same instance of data.js.
If you want to make variables in main.js available anywhere, then you can assign properties to the global object. See node.js global variables? for example. It would work fine as long as you don't over do it. With Neo's solution, you gain a little more flexibility for example with testing, because you can "inject" an arbitrary object into the module. Not every module has to use the same "global" per se.

Categories

Resources