How to get utility function from helper file on node.js server? - javascript

I have a node/express server and I'm trying to get a function from a helper file to my app.js for use. Here is the function in the helper file:
CC.CURRENT.unpack = function(value)
{
var valuesArray = value.split("~");
var valuesArrayLenght = valuesArray.length;
var mask = valuesArray[valuesArrayLenght-1];
var maskInt = parseInt(mask,16);
var unpackedCurrent = {};
var currentField = 0;
for(var property in this.FIELDS)
{
if(this.FIELDS[property] === 0)
{
unpackedCurrent[property] = valuesArray[currentField];
currentField++;
}
else if(maskInt&this.FIELDS[property])
{
//i know this is a hack, for cccagg, future code please don't hate me:(, i did this to avoid
//subscribing to trades as well in order to show the last market
if(property === 'LASTMARKET'){
unpackedCurrent[property] = valuesArray[currentField];
}else{
unpackedCurrent[property] = parseFloat(valuesArray[currentField]);
}
currentField++;
}
}
return unpackedCurrent;
};
At the bottom of that helper file I did a module.export (The helper file is 400 lines long and I don't want to export every function in it):
module.exports = {
unpackMessage: function(value) {
CCC.CURRENT.unpack(value);
}
}
Then in my app.js I called
var helperUtil = require('./helpers/ccc-streamer-utilities.js');
and finally, I called that function in app.js and console.log it:
res = helperUtil.unpackMessage(message);
console.log(res);
The problem is that the console.log gives off an undefined every time, but in this example: https://github.com/cryptoqween/cryptoqween.github.io/tree/master/streamer/current (which is not node.js) it works perfectly. So I think I am importing wrong. All I want to do is use that utility function in my app.js

The unPackMessage(val) call doesn't return anything:
module.exports = {
unpackMessage: function(value) {
CCC.CURRENT.unpack(value);
}
}
you need to return CCC.CURRENT.UNPACK(value);
module.exports = {
unpackMessage: function(value) {
return CCC.CURRENT.unpack(value);
}
}

Related

Node.js: Exported function "is not a function" in one js file, but not another

So one of my files has a function that I need two of my other files to access. I am exporting this function with module.exports = {}. For some reason, one of my files is able to call this function, while I get a commands.commandRouter is not a function error when trying to call it from the other file. Here's basically what I've got going on:
commands.js
function commandRouter(commandName, commandType) {
if (commandType == 'sound') {
console.log(`${commandName} is a sound command, executing sound function`)
playAudio.playAudio(commandName.substring(1));
}
}
module.exports = {commandRouter}
main.js
const commands = require('./modules/commands.js');
const secondary = require('./modules/secondary.js');
client.on('message', (channel, tags, message, self) => {
if(message.charAt(0) == '!'){
console.log('Trigger character identified');
if(commands.commandList.hasOwnProperty(message.toLowerCase())) {
console.log('Valid command identified')
if (commands.commandList[`${message}`] == 'random' ) {
console.log('Random-type command identified')
secondary.randomSelectPropery(message.toLowerCase().substring(1));
}
else
{
console.log('Regular command identified')
commands.commandRouter(message, commands.commandList[`${message}`]);
}
}
}
}
commands.commandRouter(paramA, paramB); works just fine in this instance
secondary.js
const commands = require('./commands.js');
var randomSelectPropery = function (commandObject) {
randomObject = eval(commandObject);
var keys = Object.keys(randomObject);
console.log(randomObject)
console.log(`This object has ${keys.length} commands to choose from`);
var newCommandName = Object.getOwnPropertyNames(randomObject)[keys.length * Math.random() << 0];
console.log(newCommandName)
var newCommandType = randomObject[`${newCommandName}`]
console.log(newCommandType);
commands.commandRouter(newCommandName, newCommandType);
};
const perfect = {
"!perfectqube": "sound",
"!perfectsf2": "sound",
};
module.exports = { perfect, randomSelectPropery }
Here, commands.commandRouter(paramA, paramB); give the commands.commandRouter is not a function error.
File structure is as follows:
.\folder\main.js
.\folder\modules\commands.js
.\folder\modules\secondary.js

load different module on preferences

I would like to process an array of image files. When selecting them I can choose between selecting them randomly or one by one (queue). The decision is hold by the config.json.
First I initialize the processor and select the right image selection module by calling processImages and pass in the array of image files.
function processImages(images) {
const imageSelector = getImageSelector();
imageSelector.init(images); // initialize the module
console.log(imageSelector.getImage()); // test
}
function getImageSelector() {
const { random } = config;
const selector = random ? 'randomSelector' : 'queueSelector';
return require(`./imageSelectors/${selector}.js`);
}
The modules itself have their own logic to return the next image. For the random module I go for
let images;
module.exports = {
init: images => {
init(images);
},
getImage: () => {
return getImage();
}
};
function init(images) {
this.images = images;
}
function getImage() {
const index = getRandomIndex();
return images[index];
}
function getRandomIndex() {
const indexValue = Math.random() * images.length;
const roundedIndex = Math.floor(indexValue);
return images[roundedIndex];
}
and for the queue module I go for
let images;
let currentImageCounter = 0;
module.exports = {
init: images => {
init(images);
},
getImage: () => {
return getImage();
}
};
function init(images) {
this.images = images;
currentImageCounter = 0;
}
function getImage() {
const index = getNextIndex();
return images[index];
}
function getNextIndex() {
if (currentImageCounter > images.length)
currentImageCounter = 0;
else
currentImageCounter++;
return currentImageCounter;
}
When I run the code and random is true I get this error
C:...\imageSelectors\randomSelector.js:22
const indexValue = Math.random() * images.length;
TypeError: Cannot read property 'length' of undefined
When calling imageSelector.init(images) some image items are available so they just are undefined within the modules.
I think I missunderstood how to work with modules correctly. Could someone tell me how to setup the code correctly?
In your module, you declare a local variable images and use it as an object field this.images which is not right. Try this approach and do not shadow the upper-level variables with deeper-level variables with the same names to not be misled (i.e. use images as outer variable and something like imgs as function parameters). I've also a bit simplified your module code to avoid some unneeded duplication.
let images;
module.exports = {
init(imgs) {
images = imgs;
},
getImage() {
const index = getRandomIndex();
return images[index];
}
};
function getRandomIndex() {
const indexValue = Math.random() * images.length;
const roundedIndex = Math.floor(indexValue);
return images[roundedIndex];
}

Pass Json to karate-config.js file

I have more than 6 environments against which i have to run the same set of rest api scripts. For that reason i have stored all that test data and the end points/resource paths in a json file. I then try to read this json file into my karate-config.js file, this is because i want to fetch the data corresponding to the environment that is being passed from the command line (karate.env), which am reading into my karate-config.js file
Below is my json file sample
[
{
"qa":{
"username_cm_on":"test_cm_on_qa",
"password_cm_on":"Test123$",
"nonadmin_username_cm_on":"test_non_admin_cm_on_qa",
"nonadmin_password_cm_on":"Test123$",
"username_cm_off":"test_cm_off_qa",
"password_cm_off":"Test123$",
"nonadmin_username_cm_off":"test_non_admin_cm_off_qa",
"nonadmin_password_cm_off":"Test123$",
"zuul_urls":{
"home-sec-uri":"https://qa.abc.com/qa/home-sec-uri",
"home-res-uri":"https://qa.abc.com/qa/home-res-uri"
}
}
},
{
"uat":{
"username_cm_on":"test_cm_on_uat",
"password_cm_on":"Test123$",
"nonadmin_username_cm_on":"test_non_admin_cm_on_uat",
"nonadmin_password_cm_on":"Test123$",
"username_cm_off":"test_cm_off_uat",
"password_cm_off":"Test123$",
"nonadmin_username_cm_off":"test_non_admin_cm_off_uat",
"nonadmin_password_cm_off":"Test123$",
"zuul_urls":{
"home-sec-uri":"https://uat.abc.com/qa/home-sec-uri",
"home-res-uri":"https://uat.abc.com/qa/home-res-uri"
}
}
}
]
and below is my karate-config.js file
function() {
// var env = karate.env; // get system property 'karate.env'
var env = 'qa';
var cm = 'ON';
var envData = call read('classpath:env_data.json'); //require("./env_data.json");
// write logic to read data from the json file _ Done, need testing
karate.log('karate.env system property was:', env);
switch(env) {
case "qa":
if(cm === 'ON'){
config.adminusername_cm_on = getData().username_cm_on;
config.adminpassword_cm_on = "";
config.nonadminusername_cm_on = getData().nonadmin_username_cm_on;
config.nonadminpassword_cm_on = "";
}else if(cm === "OFF") {
config.adminusername_cm_off = getData().username_cm_off;
config.adminpassword_cm_off = "";
config.nonadminusername_cm_off = getData().nonadmin_username_cm_off;
config.nonadminpassword_cm_off = "";
}
break;
case "uat":
break;
default:
break;
}
// This method will return the data from the env_data.json file
var getData = function() {
for(var i = 0; i < obj.length; i++) {
for(var e in obj[i]){
var username_cm_on = obj[i][e]['username_cm_on'];
var nonadmin_username_cm_on = obj[i][e]['nonadmin_username_cm_on'];
var username_cm_off = obj[i][e]['username_cm_off'];
var nonadmin_username_cm_off = obj[i][e]['nonadmin_username_cm_off'];
return {
username_cm_on: username_cm_on,
nonadmin_username_cm_on: nonadmin_username_cm_on,
username_cm_off: username_cm_off,
nonadmin_username_cm_off: nonadmin_username_cm_off
}
}
}
}
var config = {
env: env,
data: getData(),
}
return config;
}
I tried several ways to load the env-data.json file into karate-config.js as below
var envData = call read('classpath:env_data.json');
I know the above is not valid from this stackover flow answer Karate - How to import json data by Peter Thomas
So,tried with the below ones
var envData = read('classpath:env_data.json');
var envData = require("./env_data.json");
var envData = require('./env_data.json');
But, still facing issues with reading the json file. Appreciate help on this.
I think you over-complicated your JSON. You just need one object and no top-level array. Just use this as env_data.json:
{
"qa":{
"username_cm_on":"test_cm_on_qa",
"password_cm_on":"Test123$",
"nonadmin_username_cm_on":"test_non_admin_cm_on_qa",
"nonadmin_password_cm_on":"Test123$",
"username_cm_off":"test_cm_off_qa",
"password_cm_off":"Test123$",
"nonadmin_username_cm_off":"test_non_admin_cm_off_qa",
"nonadmin_password_cm_off":"Test123$",
"zuul_urls":{
"home-sec-uri":"https://qa.abc.com/qa/home-sec-uri",
"home-res-uri":"https://qa.abc.com/qa/home-res-uri"
}
},
"uat":{
"username_cm_on":"test_cm_on_uat",
"password_cm_on":"Test123$",
"nonadmin_username_cm_on":"test_non_admin_cm_on_uat",
"nonadmin_password_cm_on":"Test123$",
"username_cm_off":"test_cm_off_uat",
"password_cm_off":"Test123$",
"nonadmin_username_cm_off":"test_non_admin_cm_off_uat",
"nonadmin_password_cm_off":"Test123$",
"zuul_urls":{
"home-sec-uri":"https://uat.abc.com/qa/home-sec-uri",
"home-res-uri":"https://uat.abc.com/qa/home-res-uri"
}
}
}
And then this karate-config.js will work:
function() {
var env = 'qa'; // karate.env
var temp = read('classpath:env_data.json');
return temp[env];
}
And your tests can be more readable:
Given url zuul_urls['home-sec-uri']
If you have trouble understanding how this works, refer to this answer: https://stackoverflow.com/a/59162760/143475

Invalid Locator error

I tried to rewrite my tests in Page Object style but something goes wrong.
I use Class Tab and this is a part of my code:
var World = require('../support/world.js');
const isAllAjaxRequests = require('../scripts/util').isAllAjaxRequests;
const isElementLocatedAndVisible = require('../scripts/util').isElementLocatedAndVisible;
module.exports.Tab = class Tab {
constructor(data) {
this.name = "Base";
this.locators = {
'nextStepIsLocked': {xpath: '//md-tab-item[#aria-selected="true"]//div[#class="cc-status red"]'},
'isActiveTab': {xpath: '//md-tab-item[#aria-selected="true"]//span[text()="'+ data + '"]'}
}
}
waitForElement(bySelector) {
var driver = World.getDriver();
var self = this;
//var bySelector = self.locators[bySelector];
return driver.wait(isAllAjaxRequests(driver), waitTimeOut).then(() => {
//console.log(bySelector)
return driver.wait(isElementLocatedAndVisible(bySelector), waitTimeOut);
});
}
tabIsOpen(tabName) {
var driver = World.getDriver();
var self = this;
var bySelector = By.xpath('//md-tab-item[#aria-selected="true"]//span[text()="'+ tabName + '"]');
return self.waitForElement(bySelector);
}
}
Code in util:
exports.isElementLocatedAndVisible = function isElementLocatedAndVisible(driver, bySelector) {
return new Condition('element is located and visible', function(driver) {
console.log(bySelector)
return driver.findElements(bySelector).then((arr) => {
if (arr.length > 0) {
return arr[0].isDisplayed();
}
else {
return false;
}
});
});
};
I tried to use is in my test:
this.Then(/^Tab "([^"]*)" is open$/, function (tabName) {
this.createTab(tabName);
//var bySelector = tab.getLocator(isActiveTab);
return tab.tabIsOpen(tabName);
});
But I recieved an Invalid Locator error.
Via debug print I see thah I miss bySelector value when code go to exports.isElementLocatedAndVisible function. This is undefiened.
What I did wrong?
I suspect it is just missing of a parameter causing the issue.
In the following line:
return driver.wait(isElementLocatedAndVisible(bySelector), waitTimeOut);
add driver object as first argument and then bySelector, as follows:
return driver.wait(isElementLocatedAndVisible(driver, bySelector), waitTimeOut);
function is defined as follows:
function isElementLocatedAndVisible(driver, bySelector)
so, expecting driver object along with bySelector

Convert a text from text file to array with fs [node js]

I have a txt file contains:
{"date":"2013/06/26","statement":"insert","nombre":1}
{"date":"2013/06/26","statement":"insert","nombre":1}
{"date":"2013/06/26","statement":"select","nombre":4}
how I can convert the contents of the text file as array such as:
statement = [
{"date":"2013/06/26","statement":"insert","nombre":1},
{"date":"2013/06/26","statement":"insert","nombre":1},
{"date":"2013/06/26","statement":"select","nombre":4}, ];
I use the fs module node js. Thanks
Sorry
I will explain more detailed:
I have an array :
st = [
{"date":"2013/06/26","statement":"insert","nombre":1},
{"date":"2013/06/26","statement":"insert","nombre":5},
{"date":"2013/06/26","statement":"select","nombre":4},
];
if I use this code :
var arr = new LINQ(st)
.OrderBy(function(x) {return x.nombre;})
.Select(function(x) {return x.statement;})
.ToArray();
I get the result I want.
insert select insert
but the problem my data is in a text file.
any suggestion and thanks again.
There is no reason for not to do your file parser yourself. This will work on any size of a file:
var fs = require('fs');
var fileStream = fs.createReadStream('file.txt');
var data = "";
fileStream.on('readable', function() {
//this functions reads chunks of data and emits newLine event when \n is found
data += fileStream.read();
while( data.indexOf('\n') >= 0 ){
fileStream.emit('newLine', data.substring(0,data.indexOf('\n')));
data = data.substring(data.indexOf('\n')+1);
}
});
fileStream.on('end', function() {
//this functions sends to newLine event the last chunk of data and tells it
//that the file has ended
fileStream.emit('newLine', data , true);
});
var statement = [];
fileStream.on('newLine',function(line_of_text, end_of_file){
//this is the code where you handle each line
// line_of_text = string which contains one line
// end_of_file = true if the end of file has been reached
statement.push( JSON.parse(line_of_text) );
if(end_of_file){
console.dir(statement);
//here you have your statement object ready
}
});
If it's a small file, you might get away with something like this:
// specifying the encoding means you don't have to do `.toString()`
var arrayOfThings = fs.readFileSync("./file", "utf8").trim().split(/[\r\n]+/g).map(function(line) {
// this try/catch will make it so we just return null
// for any lines that don't parse successfully, instead
// of throwing an error.
try {
return JSON.parse(line);
} catch (e) {
return null;
}
// this .filter() removes anything that didn't parse correctly
}).filter(function(object) {
return !!object;
});
If it's larger, you might want to consider reading it in line-by-line using any one of the many modules on npm for consuming lines from a stream.
Wanna see how to do it with streams? Let's see how we do it with streams. This isn't a practical example, but it's fun anyway!
var stream = require("stream"),
fs = require("fs");
var LineReader = function LineReader(options) {
options = options || {};
options.objectMode = true;
stream.Transform.call(this, options);
this._buffer = "";
};
LineReader.prototype = Object.create(stream.Transform.prototype, {constructor: {value: LineReader}});
LineReader.prototype._transform = function _transform(input, encoding, done) {
if (Buffer.isBuffer(input)) {
input = input.toString("utf8");
}
this._buffer += input;
var lines = this._buffer.split(/[\r\n]+/);
this._buffer = lines.pop();
for (var i=0;i<lines.length;++i) {
this.push(lines[i]);
}
return done();
};
LineReader.prototype._flush = function _flush(done) {
if (this._buffer.length) {
this.push(this._buffer);
}
return done();
};
var JSONParser = function JSONParser(options) {
options = options || {};
options.objectMode = true;
stream.Transform.call(this, options);
};
JSONParser.prototype = Object.create(stream.Transform.prototype, {constructor: {value: JSONParser}});
JSONParser.prototype._transform = function _transform(input, encoding, done) {
try {
input = JSON.parse(input);
} catch (e) {
return done(e);
}
this.push(input);
return done();
};
var Collector = function Collector(options) {
options = options || {};
options.objectMode = true;
stream.Transform.call(this, options);
this._entries = [];
};
Collector.prototype = Object.create(stream.Transform.prototype, {constructor: {value: Collector}});
Collector.prototype._transform = function _transform(input, encoding, done) {
this._entries.push(input);
return done();
};
Collector.prototype._flush = function _flush(done) {
this.push(this._entries);
return done();
};
fs.createReadStream("./file").pipe(new LineReader()).pipe(new JSONParser()).pipe(new Collector()).on("readable", function() {
var results = this.read();
console.log(results);
});
fs.readFileSync("myfile.txt").toString().split(/[\r\n]/)
This gets your each line as a string
You can then use UnderscoreJS or your own for loop to apply the JSON.parse("your json string") method to each element of the array.
var arr = fs.readFileSync('mytxtfile', 'utf-8').split('\n')
I think this is the simplest way of creating an array from your text file

Categories

Resources