All I am trying to do is to export two functions from a module. One function taking an argument and the other with no argument:
function initClass(params)
{
return new Promise( (resolve, reject) => {
if (!wallet) {
wallet = new WalletClient(params);
resolve(wallet);
} else {
console.log('Wallet is initialized');
resolve(wallet);
}
});
}
function getInstance()
{
return wallet;
}
For initClass(params) only, I can do this as:
module.exports = (params) => {
initClass(params)
}
And then I call this as:
var init = require('./class.js')(params).initClass(params);
This works fine.
Now, for me to export getInstance() as well, I have tried to do the following but it doesn't seem to work.
module.exports = (params) => {
initClass(params),
getInstance
}
This complaints that there is no function getInstance.
Then I tried this:
module.exports.init = (params) => {
initClass(params)
}
module.exports.instance = {
getInstance
}
Then call them as:
var init = require('./class.js').init(params).initClass(params);
What is the proper way to export multiple functions like this?
Thank you.
You're making it more complex than needed. Once you have your functions defined, you can export it with this:
module.exports = {
initClass,
getInstance
}
To use it, you do this:
const init = require("./class.js");
init.initClass(params);
const instance = init.getInstance();
What you're exporting from the module is an object (which I've named init in the example above) that contains two functions. You don't have to pass arguments to the functions at the time you require.
module.exports is basically an object with keys which can refer to any variables/functions of your file.In your case,
module.exports.initClass = function (params){
...
}
module.exports.getInstance = function (){
}
When importing it
var init = require('./class.') // init object has two keys -> initClass and getInstance
init.initClass('abc')
init.getInstance()
If i'm understanding correctly you are trying to export multiple methods if that is the case simple use this.
module.exports = {
method: function() {},
otherMethod: function(parmas) {}
}
In your code use like this.
var init = require('./class.js');
init.method()
init.otherMethond(paramObj)
If you want below scenario you need to check out about method chaining.
var init = require('./class.js').init(params).initClass(params);
Related
I am quite new at SAPUI5 and JS. There is something I do not understand well concerning the module definition and usage. Here is my context:
I want to create a Component my.test.comp that uses an external module object my.test.comp.Service.
So following the best practices, I have the following code:
Service.js:
sap.ui.define([
"sap/ui/base/Object"
], function(BaseObject) {
"use strict";
var modulePath = jQuery.sap.getModulePath("my.test.comp");
var SERVICE_ROOT_PATH = modulePath.lastIndexOf("/") > 0
? modulePath.substring(0, modulePath.lastIndexOf("/"))
: "/test";
var Service = BaseObject.extend("my.test.comp.Service", {
getServiceRootPath: function () {
return SERVICE_ROOT_PATH;
}
});
return Service;
});
And I use this in the Component.js:
sap.ui.define([
"sap/ui/core/Component",
"./Service"
], function(Component, Service) {
"use strict";
return Component.extend("my.test.comp.Component", {
init: function() {
var serviceRootPath = Service.getServiceRootPath();
jQuery.sap.log.error("ServicePathInfo : " + serviceRootPath);
}
});
});
When I run this, I get an error saying that getServiceRootPath is undefined, and throws an error.
So I changed the Service.js as follow:
sap.ui.define([
"sap/ui/base/Object"
], function(BaseObject) {
"use strict";
var modulePath = jQuery.sap.getModulePath("my.test.comp");
var SERVICE_ROOT_PATH = modulePath.lastIndexOf("/") > 0
? modulePath.substring(0, modulePath.lastIndexOf("/"))
: "/test";
var Service = BaseObject.extend("my.test.comp.Service");
Service.getServiceRootPath = function () {
return SERVICE_ROOT_PATH;
};
return Service;
});
And now it is working well. I do not understand what are the differences.
Could someone explain me why?
In JS, there are no classes. There are either plain objects ({}) or functions with constructor that can be called with new.
Accordingly, calling .extend("...") in UI5 returns a function, again, with its constructor as any other functions, ready to be used with new. Your module members (methods, properties, etc.) will be added to the prototype and not to the parent function (Service) itself.
BaseObject.extend("my.test.comp.Service", {
// methods in prototype ...
});
The required Service module (i.e. function) consists of only a constructor function (Service.constructor) and a prototype object (Service.prototype). That is why Service.getServiceRootPath was undefined in your first case. You'll need to call the constructor function with new first:
return Component.extend("my.test.comp.Component", {
init: function() {
const service1 = new Service(); /* returns an object with ..
* __proto__: {
* getServiceRootPath: f ()
* }
*/
const serviceRootPath = service1.getServiceRootPath();
// ...
},
});
(You could also directly access the method with Service.prototype.getServiceRootPath without new)
This also explains why Service.getServiceRootPath worked in the second case. You can add pretty much anything you like to an existing function since functions are ultimately objects too 🙂
It looks like your intention was not to create multiple "services" but a simple object with methods in it. In that case, just return a simple object with methods in your module definition.
sap.ui.define([
// Without "sap/ui/base/Object"
], function() {
"use strict";
//...
return {
getServiceRootPath: function () {
// ...
},
};
});
sap.ui.define([
"sap/ui/core/Component",
"./Service",
], function(Component, Service) {
"use strict";
return Component.extend("my.test.comp.Component", {
init: function() {
const serviceRootPath = Service.getServiceRootPath();
// ...
},
});
});
This will work too.
In your component.js you should import
"my/test/comp/Service"
instead of
"./Service"
I am trying to access the function from another file like below:
exp1.js
module.exports = function(RED) {
function expIn(config) {
//some code
}
}
I want to access "expIn()" in another file called exp2.js how can i achieve this??
please help me.
As is, you are not exporting expIn(). You are exporting the outer function in which expIn() is declared and defined. expIn() is just a local variable and cannot be accessed outside of the anonymous outer function you are actually exporting. To make it visible to other files, you either have to export it directly or define it on the exported function.
You're missing some code, but you have 3 options for accessing expIn() outside of exp1.js. First is to export it directly
exp1.js
module.exports = function expIn(config) {
// Code...
};
exp2.js
const { expIn } = require('exp1.js');
expIn({/*config*/});
Alternatively, you could add expIn() to the outer function's prototype. This is usually done when you want to export a class with several methods attached to it. You can do this one of 2 ways. First, the method most similar to what you're already doing is
exp1.js
module.exports = function ClassName(/*constructor args*/) {
this.expIn = function expIn(config) {
// Code...
};
// Other initialization...
};
Alternatively, you could define expIn() more explicitly on the prototype using this method:
exp1.js
function ClassName(/*constructor args*/) {
// Initialize class.
}
ClassName.prototype.expIn = function expIn(config) {
// Code...
};
module.exports = ClassName;
Regardless of which of the 2 methods you choose above, you would access it as
const ClassName = require('exp1.js');
let classInstance = new ClassName();
classInstance.expIn({/*config options/*});
One last method you could use is defining expIn() as a static method on the function class. This would look like:
exp1.js
function ClassName(/*constructor args*/) {
// Initialization code...
}
ClassName.expIn = function expIn(config) {
// Code...
};
module.exports = ClassName;
exp2.js
const ClassName = require('exp1.js');
ClassName.expIn(/*config options*/);
This i resolved by adding function out side the function(RED):
module.exports = function(RED) {
}
function expIn(config) {
//some code
}
And then exported as normal like :
module.exports.expIn = expIn;
then it starts working.
I am not sure whether this is a correct method or not but it serves my requirement.
If I want to use an object and its methods in another file, how would I set up my module.exports?
Object:
var Object = function ()
{
...
}
Object.prototype.foo = function (param)
{
...
}
Module.export:
module.exports = {
Object : Object
}
or
module.exports = {
Object : Object,
foo : Object.prototype.foo
}
?
A few ways of doing this but if you're trying to access prototype methods from your other file, then you'll need to instantiate your constructor,
something like:
For ex:
// lib.js
var YourThing = function () {
}
YourThing.prototype.someMethod = function () {
console.log('do something cool');
}
module.exports = YourThing;
// index.js
var YT = require('./lib.js');
var yourThing = new YT();
yourThing.someMethod();
module.exports = Object;
This will export your Object as a Module.
If your object is not renewed in your app, the best way to use it as an executed function with late binding of its prototype methods
const _ = require('lodash')
var Object = function ()
{
..
_.bindAll(this); // at last bind all methods. this way you won't miss a method
}
Object.prototype.foo = function (param)
{
...
}
module.exports = new Object();
then you can call the functions like,
const myObj = require('./object-file')
myObj.myMethod();
If you need reusable component,
module.exports = Object;
const _obj = require('./object-file'); // you can call this way anywhere in any function and for every require, it creates a new object.
var object = new _obj();
_obj.anyMethod();
This is a follow-up question to In Node.js, how do I "include" functions from my other files?
I would like to include an external js file that contains common functions for a node.js app.
From one of the answers in In Node.js, how do I "include" functions from my other files?, this can be done by
// tools.js
// ========
module.exports = {
foo: function () {
// whatever
},
bar: function () {
// whatever
}
};
var zemba = function () {
}
It is inconvenient to export each and every function. Is it possible to have a one-liner that exports all functions? Something that looks like this;
module.exports = 'all functions';
It is so much more convenient this way. It is also less buggy in case one forgets to export certain functions later.
If not a one-liner, are there simpler alternatives that make coding more convenient? I just want to include an external js file made up of common functions conveniently. Something like include <stdio.h> in C/C++.
You can write all your function declarations first and then export them in an object:
function bar() {
//bar
}
function foo() {
//foo
}
module.exports = {
foo, bar
};
There's no magical one-liner though, you need to explicitly export the functions you want to be public.
I have done something like the following:
var Exported = {
someFunction: function() { },
anotherFunction: function() { },
}
module.exports = Exported;
I require it in another file and I can access those functions
var Export = require('path/to/Exported');
Export.someFunction();
This is essentially just an object with functions in it, and then you export the object.
A really old question but I just had to solve the same issue myself.
the solution I used was to define a Class inside the module to contain all my functions and simply export an instance of the class.
classes.js looks like this:
class TestClass
{
Function1() {
return "Function1";
}
Function2() {
return "Function2";
}
}
module.exports = new TestClass();
app.js looks like this:
const TestClass = require("./classes");
console.log( TestClass.Function1);
just keep adding more functions to the class and they will be exported :)
It is worth noting that in ES6, you can now export functions like this:
export function foo(){}
export function bar(){}
function zemba(){}
Simply write export before the functions you want to export. More information here.
If you use ES6 you can do something like that:
function bar() {
//bar
}
function foo() {
//foo
}
export default { bar, foo };
const fs = require("fs")
var ExportAll = {
deleteFile : function deleteFile(image,folder="uploads"){
let imagePath = `public/${folder}/${image}`
if (fs.existsSync(imagePath)){
fs.unlinkSync(imagePath)
}
},
checkFile : function checkFile(image,folder="uploads"){
let imagePath = `public/${folder}/${image}`
if (fs.existsSync(imagePath)){
return true
}
else{
return false
}
},
rand : function(min=1,max=10)
{
return Math.floor((Math.random() * max) + min)
}
}
module.exports = ExportAll
Import everything from a type module file that has functions that are exported.
Found here:
https://javascript.info/import-export
myfile.js
export function myFunction()
{
// ................
}
export function myFunction2()
{
// ................
}
myfile2.js - import everything that is exported in the file
import * as myFunctions from './myfile.js';
// Usage
myFunctions.myFunction();
myFunctions.myFunction2();
I have read a lot of articles about how to create modules in node.js, and you can use module.exports to expose module internals to the file which includes it.. awesome!
How does this work the other way around? I'll use the following as an example :-)
USER.JS
function User() {
this.property = 'value';
this.doSomething = function() {
var getStuff = mainFileFunction();
// do something with getStuff
}
module.exports = User;
MAIN.JS
var myArray = [];
myArray.push('something');
myArray.push('something else');
mainFileFunction() {
for(thing in myArray) {
return myArray[thing];
}
}
var u = new user();
log(u.property); <--- THIS IS EXPOSED, COOL!
u.doSomething(); <--- This will throw an error because mainFileFunction is not defined in user.js :-(
If I were to move mainFileFunction to the user file, then it still wouldn't work because the myArray array wouldn't be defined... and if I were to move that over too, I wouldn't be able to use it in other functions in main (which I want to) :-)
I'm sorry if I'm missing something really obvious here... What I want is to expose the parts of my choosing from modules I include (module.export works for that) but I also want to expose everything from the main file to all the includes..
or just expose everything to everything? is that totally messy and horrible??
Just to explain what I am trying to do here... I want to have classes defined in separate files, but I want to instantiate a bunch of them as objects in the main file and store them in arrays.. I want the objects to contain methods which can access arrays of the other object types.
Thanks guys! :-)
You can use globals, or have a proper circular dependency (requireing both files), however - this is usually a bad habit which can lead to maintainability problems in the future.
Instead, you can use dependency injection and inject doSomething into your module.
This basically gives you the following for free:
You can test User with a simple mock implementation of doSomething later and verify the correctness of your code
The dependencies of a user are explicit and not implicit, which makes it obvious what a user needs.
I'll provide two implementations, one using constructor dependency injection and one with a module wide setting.
USER.JS
function User(dependentFunction) {
this.property = 'value';
this.doSomething = function() {
var getStuff = dependentFunction();
// do something with getStuff
}
}
module.exports = User;
MAIN.JS
...
var u = new User(mainFileFunction);
u.doSomething(); // this will now work, using mainFileFunction
What happens here is fairly simple, and we know what's going on.
This can also be a module wide setting
USER.JS
function User(depFunc) {
this.property = 'value';
this.doSomething = function() {
var getStuff = depFunc();
// do something with getStuff
}
}
function UserFactory(depFunc){
return function(){
return new User(depFunc);
}
}
module.exports = UserFactory;
MAIN.JS
var getUser = UserFactory(mainFileFunction);
var u = getUser(); // will return a new user with the right function
+1 to Benjamin answer for dependency injection.
I would like to add another way to inject objects in your modules by passing the dependency in the require like require('./module.js')(dependentFunction);
//MAIN.js
var db = function() {
this.rows = [];
this.insert = function(name) {
this.rows.push(name);
console.log('Db: Inserting user with name ' + name);
}
this.getAll = function(){
return this.rows;
}
}
var fakeDb = new db();
var user = require('./user.js')(fakeDb);
user.add('Jhon');
user.add('Rose');
user.list();
and
//users.js
module.exports = function(db) {
return {
add: function(name) {
db.insert(name);
},
list: function() {
var users = db.getAll();
var i = users.length;
console.log('listing users\n-------');
while(i--) {
console.log(users[i]);
}
}
}
}
You should pass mainFileFunction as a parameter to the constructor of user.
USER.JS
function User(mainFileFunction) {
this.property = 'value';
this.doSomething = function() {
var getStuff = mainFileFunction();
// do something with getStuff
}
module.exports = User;
In your main.js use the following
var u = new user(mainFileFunction);
How about moving mainFileFunction to user.js, and have the function accept an array as an argument:
mainFileFunction(array) {
for(thing in array) {
return array[thing];
}
}
And then when you call it from main.js, pass the function your array:
u.doSomething(myArray);