How to use "require" dynamically in javascript? - javascript

I have a javascript function in "sample.js" file. It is like this:
var mapDict = { '100': 'test_100.js', '200': 'test_200_API.js', '300': 'test_300_API.js' }
function mapAPI()
{
this.version = 0.1;
}
mapAPI.prototype.getFileName = function( id ) {
return mapDict[id]
}
module.exports = mapAPI;
in another file named "institute.js" I want to require the above "test_xxx_API" files dynamically. I have the following code:
const mapAPI = require('../../sample.js');
const map = new mapAPI();
const mapFile = map.getFileName("100");
var insAPI = require(mapFile);
When I run this code by "node institute.js" command, I get the following error:
Error: Cannot find module './test_100_API.js'.
But the "test_100_API.js" file exists and is located in the current folder besides "institute.js". When I changed var insAPI = require(mapFile); to var insAPI = require("./test_100_API.js"); and give it the exact path instead of dynamic path, it works fine. Can anyone help me?
Thanks in advance

Related

google appscript to move folder content to another folder

I am new at this and not programmer or a coder.
I am trying to make google app script to move folder content to another folder in google drive
I came across this link
I am using below code and it runs without error, but the files are not moved.
function myFunction() {
var source_folder = DriveApp.getFolderById('1fMCHA4-b2a2BQjO0VD2dd5m4V5WvXz9D')
var dest_folder = DriveApp.getFolderById('1LbZchJflfcnOKqSPYCdGcFTI_7AAVJIi')
function moveFiles(source_folder, dest_folder){
var files = source_folder.getFiles();
while (files.hasNext()) {
var file = files.next();
dest_folder.addFile(file);
source_folder.removeFile(file);
}
}
}
Can someone advise.
Try:
function myFunction() {
const source_folder = DriveApp.getFolderById('1fMCHA4-b2a2BQjO0VD2dd5m4V5WvXz9D')
const dest_folder = DriveApp.getFolderById('1LbZchJflfcnOKqSPYCdGcFTI_7AAVJIi')
// Call the function:
moveFiles(source_folder, dest_folder)
function moveFiles(source_folder, dest_folder) {
const files = source_folder.getFiles()
while (files.hasNext()) {
const file = files.next()
file.moveTo(dest_folder)
}
}
}
Rather than copy and delete each file, just move it!
The main problem you had was that you were not calling your function. You had only defined it.
Learn More:
File.moveTo()
Similar to the first answer but uses the Drive API to perform the move
function movefiles() {
const sfldr = DriveApp.getFolderById('sid');
const dfldr = DriveApp.getFolderById('did');
const files = sfldr.getFiles()
while (files.hasNext()) {
const file = files.next()
Drive.Files.update({ "parents": [{ "id": dfldr.getId() }] }, file.getId(), null, { supportsAllDrives: true });
}
}
Drive.Files.update

Move Files in google script

i use the function MoveFiles() to copy file into other folder.
But when i ran it, i try to delete the file in the original folder. After deleted it, i saw that the file that i moved also deleted.
How to make the file that i moved not be deleted too?
Tqvm
function MoveFiles() {
var SourceFolder = DriveApp.getFolderById('1WIZxuF_r9I-510Kfw9N0AImcS1Uf63dC');
var SourceFiles = DriveApp.getFolderById('1QfFl5JIfOYaTXZyFpuBNSMzBdBrXLll9').getFiles();
var DestFolder = DriveApp.getFolderById('1_03PnkJlt6mTo5bAExUMOdZVVkzMAUsA');
while (SourceFiles.hasNext()) {
var file = SourceFiles.next();
DestFolder.addFile(file);
SourceFolder.removeFile(file);
}
}
Try switching the code line for delete and add. According to this related SO post:
I've found that I needed to reverse the last two lines (so the removeFile is done first) otherwise the removeFile actually just removes it from the folder it was just added to and not from the original parent.
I've tested it and actually get the correct result, here is my code snippet:
function myFunction() {
var folder = DriveApp.getFolderById('sourceID');
var destinationFolder = "destinationID";
var contents = folder.getFiles();
while (contents.hasNext()){
var file = contents.next();
moveFiles(file.getId(),destinationFolder);
}
}
function moveFiles(sourceFileId, targetFolderId) {
var file = DriveApp.getFileById(sourceFileId);
file.getParents().next().removeFile(file);
DriveApp.getFolderById(targetFolderId).addFile(file);
}
Hope this helps.

Exporting class type containing multiple values

I wrote some code here that takes data from a .JSON file and turns it into an stringified object.
I need to export the Source and Destination classes here:
class Source {
constructor(source_address, source_lat, source_lng, scan_type) {
this.source_address = source_address;
this.source_lat = source_lat;
this.source_lng = source_lng;
}
};
class Destination {
constructor(dest_address, dest_lat, dest_lng, scan_type) {
this.dest_address = dest_address;
this.dest_lat = dest_lat;
this.dest_lng = dest_lng;
this.scan_type = scan_type;
}
};
that I initialize like so:
//Initialize Source
obj.forEach(block => {
//initialize Values
var sourceClass = new Source(block.source_address, block.source_lat, block.source_lng, block.scan_type);
});
...
//Initialize Destination
obj.forEach(block => {
//initialize Destination
var destinationClass = new Destination(block.dest_address, block.dest_lat, block.dest_lng, block.scan_type);
});
into a separate JavaScript file.
I've tried using module.export(), and "requiring" my javascript file, but nothing seems to work.
How can I export my Source and Destination class with all it's values to another Javascript file?
In your module:
exports.Source = Source;
exports.Destination = Destination;
Using it:
var mod = require("yourmodule");
var Source = mod.Source;
var Destination = mod.Destination;
If you're using ES2015 (even though ES2015 modules aren't supported by NodeJS yet), you can use destructuring syntax to simplify use a bit:
let { Source, Destination } = require("yourmodule");
(Which looks similar to what import will look when ES2015 modules are supported [but works fundamentally differently].)

Node.js, require all modules in folder and use loaded module directly

In MyModule folder, I have this two JS files.
SayHello.js
module.exports.SayHello = function() {
return('Hello !');
}
SayByeBye.js
module.exports.SayByeBye = function() {
return('Bye Bye!');
}
In Node.js, I want to require all files in MyModule folder and call function SayHello & SayByeBye directly something like:
require(./MyModule)
console.log(SayHello());
console.log(SayByeBye());
EDIT:
With answer of #Yanick Rochon,I do this :
> ./app/my-module/index.js
global.SayHello = require('./my-module/SayHello').SayHello;
global.SayByeBye = require('./my-module/SayByeBye').SayByeBye;
> ./app/my-module/say-hello.js
module.exports.SayHello = function() {
return('Hello !');
};
> ./app/my-module/say-byebye.js
module.exports.SayByeBye = function() {
return('Bye Bye !');
};
> ./app/main.js
require('./my-module');
console.log(SayHello());
console.log(SayByeBye());
There's a section about global objects in the node documentation.
However, globals should be used with care. By adding modules to the global space I reduce testability and encapsulation. But in this case, I think using this method is acceptable.
First thing first...
I believe you are mistaking Node.js with PHP or .Net, in the sense that you don't "import" into the current module what is exported in other modules. Not unless you manually do it anyway. For example, when you call
require('./my-module');
(Note that I renamed your MyModule into Node.js naming convention.)
You don't load things into the current context; you just load the script and don't assign it to anything. To access what my-module exposes, you need to assign it, or use it directly. For example :
require('./my-module').someFunction();
or
var myModule = require('./my-module');
myModule.someFunction();
Modules are not namespaces, but JavaScript objects that exposes public properties outside of their own contexts (i.e. using module.exports = ...)
Answer
You have two most popular ways to accomplish this :
Solution 1
Create an index.json file inside your folder where you want to load all of your scripts. The returned JSON object should be all the modules to load automatically :
> ./app/index.json
[
"say-hello.js",
"say-goodbye.js"
]
You should also consider having all your files API compatible :
> ./app/say-hello.js
module.exports = function sayHello() {
return 'Hello !';
};
> ./app/say-goodbye.js
module.exports.sayGoodbye = function () {
return 'Goodbye !';
};
Then load and execute everything like this :
var path = require('path');
var basePath = './app/';
var files = require(basePath);
var mods = files.forEach(function (loaded, file) {
var mod = require(path.join(basePath, file));
// mod is a function with a name, so use it!
if (mod instanceof Function) {
loaded[mod.name] = mod;
} else {
Object.keys(mod).forEach(function (property) {
loaded[property] = mod.property;
});
}
}, {});
mods.sayHello();
mods.sayGoodbye();
Solution 2
Read all .js files inside your folder and import them. I highly recommend you use glob for this.
var glob = require("glob")
var path = require('path');
var basePath = './app/';
var mods = glob.sync(path.join(basePath, '*.js')).reduce(function (loaded, file) {
var mod = require(file);
// mod is a function with a name, so use it!
if (mod instanceof Function) {
loaded[mod.name] = mod;
} else {
Object.keys(mod).forEach(function (property) {
loaded[property] = mod.property;
});
}
return loaded;
}, {});
mods.sayHello();
mods.sayGoodbye();
Note on the difference between module.exports and exports
Typically module.exports === exports, but it is recommended to use module.exports for the following reason
exports = function Foo() { } // will not do anything
module.exports = function Foo() { } // but this will do what you expect
// however these two lines produce the same result
exports.foo = 'Bar';
module.exports.foo = 'Bar';
For this reason, module.exports is recommended in all cases.
It's not perfect, but something like this should help you accomplish this:
var fs = require('fs');
var path = require('path');
var files = fs.readdirSync(__dirname);
var ownFilename = __filename.substr(__filename.lastIndexOf(path.delimiter) + 1);
var modules = {};
for (var i = 0; i < files.length; i++) {
var filename = files[i];
if (filename.substr(-3) === '.js' && filename !== ownFilename) {
modules[filename.slice(0, -3)] = require('./' + filename);
}
}
console.log(modules.SayByeBye());
console.log(modules.SayHello());

Test context missing in before and after test hook in nightwatch js globals

I have multiple nightwatch tests with setup and teardown in every single test. I am trying to unify it into globalModule.js in before after(path set in globals_path in nightwatch.json).
//globalModule.js
before:function(test, callback){
// do something with test object
}
//sampletest.js
before: function(test){
..
},
'testing':function(test){
....
}
My problem is test context is not available in globalsModule.js. How do i get it there? Can someone let me know?
Test contex not available now. As said beatfactor, it will available soon.
While it not available try use local before first file, but it hack.
Also you can export all your file into one object and export it into nightwatch, but then you can use local before just in time.
For example:
var tests = {};
var befores = [];
var fs =require('fs');
var requireDir = require('require-dir');
var dirs = fs.readdirSync('build');
//if you have dirs that should exclude
var usefull = dirs.filter(function(item){
return !(item=='data')
});
usefull.forEach(function(item){
var dirObj = requireDir('../build/' + item);
for(key in dirObj){
if(dirObj.hasOwnProperty(key))
for(testMethod in dirObj[key])
if(dirObj[key].hasOwnProperty(testMethod))
if(testMethod == 'before')
befores.push(dirObj[key][testMethod]);
else
tests[testMethod] = dirObj[key][testMethod];
}
});
tests.before = function(browser){
//some global before actions here
//...
befores.forEach(function(item){
item.call(tests,browser);
});
};
module.exports = tests;
For more information https://github.com/beatfactor/nightwatch/issues/388

Categories

Resources