Javascript Protractor - Seeing outside functions as undefined - javascript

In specs/Test.js is a test definition: "regex2"
In pages/TablePage.js is a page object
in regex2 there is a try to use a function from TablePage.js
it('regex2', function(){
table_page.matchPriceRegex(table_page.workingBalanceField)
});
it is saying table_page.matchPriceRegex is not a function
The function itself from TablePage.js:
var TablePage = (function () {
function TablePage() {
this.workingBalanceField = element(By.xpath('//*[#id="root"]/main/section/div/div/div[5]/div/div[1]'));
}
TablePage.prototype.matchPriceRegex = function (locator) {
this.text = locator.getText();
expect(this.text).toMatch("\d{0,3}?,?\d{0,3}?\.?\d{0,3}?");
};
});
module.exports = TablePage;
The require's are incorporated with the spec file so it should see it
var TablePage = require("./../pages/TablePage");
var table_page = new TablePage();
var protractor = require("protractor");
var jasmine = require("jasmine-node");
var browser = protractor.browser;
var number = 0;
When in my IDE(WebStorm) I hold ctrl and click on the function name it redirects me correctly, as it sees it
The typeof the functions or variables form TablePage is undefined
Do you know where is the problem?

The error comes from TablePage.js, it should be.
var TablePage = (function () {
function TablePage() {
this.workingBalanceField = element(By.xpath('//*[#id="root"]/main/section/div/div/div[5]/div/div[1]'));
}
TablePage.prototype.matchPriceRegex = function (locator) {
this.text = locator.getText();
expect(this.text).toMatch("\d{0,3}?,?\d{0,3}?\.?\d{0,3}?");
};
return TablePage; // return the class as outer function return value
})();
// `(function(...){})` return a function, you should use `()` to execute the
// return function to get the returned class: TablePage.
module.exports = TablePage;

Related

Javascript execution error in Sublime

I am learning JavaScript and this is my 1st week :)
var Module = (function () {
// code
var publicMethod = {};
var privateMethod = function(someStringToBePassed) {
debug("I love USA. "+someStringToBePassed);
}
publicMethod.someFunction = function() {
privateMethod("USA is sexy");
}
return publicMethod;
})();
debug(Module.someFunction());
I am executing this in Sublime. I am seeing the following result.
--> I love USA. USA is sexy
--> undefined
Please explain why I am seeing undefined here.
[Finished in 0.0s]
Please tell me why I am seeing "undefined" in the results
You're not returning anything from someFunction. Try this:
Now someFunction returns the value of privateMethod. privateMethod returns the constructed string.
var Module = (function () {
// code
var publicMethod = {};
var privateMethod = function(someStringToBePassed) {
return "I love USA. "+someStringToBePassed;
}
publicMethod.someFunction = function() {
return privateMethod("USA is sexy");
}
return publicMethod;
})();
debug(Module.someFunction());
var Module = (function () {
//code
var publicMethod = {};
var privateMethod = function(someStringToBePassed) {
return ("I love USA. "+someStringToBePassed);
}
publicMethod.someFunction = function() {
return privateMethod("USA is sexy");
}
return publicMethod;
})();
var sample = Module;
console.log(sample.someFunction())

Call a function whose name is stored in a variable [duplicate]

This question already has answers here:
How to execute a JavaScript function when I have its name as a string
(36 answers)
Closed 7 years ago.
I have the following script:
(function () {
var Module = (function () {
var fctToCall = function () {
alert('Foo');
};
return {
fctToCall: fctToCall
};
})();
var Module2 = (function () {
var init = function () {
var str = 'fctToCall';
Module.str(); // here
};
return {
init: init
};
})();
})();
So I want to call this fctToCall method by its name - how can I do that? So far I know 3 methods:
by attaching the function to the window object, but then it wouldn't be local and in closure, and I wouldn't have the access to other local variables
eval, the best options as far as I see it, but it's still eval, so I don't wanna use it
this, but it's another architecture, I don't wanna change it
How can I solve this?
To call function use
Module[str]();
As Module is an object, you can access the dynamic properties and methods of it by using the bracket notation.
(function() {
var Module = (function() {
var fctToCall = function() {
console.log('Foo');
};
return {
fctToCall: fctToCall
};
})();
var Module2 = (function() {
var init = function() {
var str = 'fctToCall';
// Call as
Module[str]();
};
return {
init: init
};
})();
Module2.init();
})();
Replace:
var init = function () {
var str = 'fctToCall';
Module.str(); // here
};
With:
var init = function () {
var str = 'fctToCall';
Module[str](); // here
};
Here, str is used as key to access the fctToCall function on Module.
Then you can call Module2.init(), in your IIFE:
(function() {
var Module = (function() {
var fctToCall = function() {
document.write('Foo'); // (alert is broken in snippets)
};
return {
fctToCall: fctToCall
};
})();
var Module2 = (function() {
var init = function() {
var str = 'fctToCall';
Module[str](); // Access & call `fctToCall`.
};
return {
init: init
};
})();
Module2.init(); // Call `init`.
})();
Since everything in JS is object you can use the object notation.
Module[str]();
You can just invoke the function like this:
Module[str]();

Multiple Factories in Node?

Trying to create multiple factories in Node. Do they have to be in separate files? If they are, how do I make sure to access both?
index.js
var myFunc = function () {
this.data = {
thingOne: null,
thingTwo: null,
thingThree: null
};
this.fill = function (info) {
for (var prop in this.data) {
if (this.data[prop] !== 'undefined') {
this.data[prop] = info[prop];
}
}
};
this.triggerAction = function () {
//make some action happen!
};
module.exports = function (info) {
var instance = new myFunc();
instance.fill(info);
return instance;
};
When I add another function below that it breaks the existing code with an object [object Object] has no method 'triggerAction:'
var myFunc2 = function () {
this.data = {
thingOne: null,
thingTwo: null,
thingThree: null
};
this.fill = function (info) {
for (var prop in this.data) {
if (this.data[prop] !== 'undefined') {
this.data[prop] = info[prop];
}
}
};
this.triggerAction2 = function () {
//make some action happen!
};
};
module.exports = function (info) {
var instance = new myFunc2();
instance.fill(info);
return instance;
};
So do I have to put the second function in a separate file? And if I do, how do I modify package.json to make sure it sees the second file? Thanks!
The short answer is no.
The error you are seeing is caused because you are overwriting the value of the exports property of the module - effectively replacing the first assignment with the last.
If you want these to be in the same module, you would need to export them separately:
module.exports.factoryA = function(...) {...}
module.exports.factoryB = function(...) {...}
To reference these from another module either of these patterns would work:
var factories = require('./myfactories');
var factoryAResult = factories.factoryA(...);
var factoryBResult = factories.factoryB(...);
or
var factoryA = require('./myfactories').factoryA;
var factoryAResult = factoryA(...);

Javascript: Modify array directly only within its own function

I have a very simple function:
var errorsViewModel = function () {
var self = this;
var _errors = ko.observableArray([]);
self.get = function () {
return _errors;
};
self.insert = function ( error ) {
_errors.push(error);
};
}
What I want to acomplish is make _errors array modifiable directly only within its own function. That is users from outside can get the array for reading through the get method and insert itsert items only through the insert method.
But not to be able to do something like this:
var err = new errorsViewModel();
var array = err.get();
array.push('item');
Instead use the errorsViewModel interface :
err.insert('some error');
Is that possible?
Just copy the returned array:
self.get = function () {
return _errors.slice(0);
};
That way, when get is called, the caller can make changes to it if they want - but it won't modify the original.
To make sure that your array isn't accessible from outside your scope I would suggest that you expose the array via a ko.computed and then notify it's listeners on an insert.
var errorsViewModel = function () {
var self = this;
var _errors = [];
self.errors = ko.computed(function () {
return self.get();
});
self.get = function () {
return _errors.splice(0);
};
self.insert = function ( error ) {
_errors.push(error);
self.errors.valueHasMutated();
};
}

Javascript module pattern, nested functions, and sub modules

I am trying to wrap my head around javascript modules, but I'm unsure how to split up a module into further sub modules. I have read that nested functions are not really a great idea, due to performance, so how do I break up a function in a module? For example, lets say I have the following module:
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
// This is where I need to define a couple smaller functions
// should I create a new module for bigFunction? If so, should it be nested in Editor.build somehow?
}
};
})();
bigFunction is only related to Editor.build. Should I attach the smaller functions that make up bigFunction to the prototype bigFunction object? I'm not even sure if that would make sense.
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
bigFunction.smallFunction();
bigFunction.prototype.smallFunction = function(){ /*do something */ };
// not sure if this even makes sense
}
};
})();
Can someone please throw me in the right direction here? There is so much misleading information online, and would just like a definite guide on how to deal with this sort of modularization.
Thank you.
Here is a snippet I use to make names for an input:
var dynamicCounter = 0;
//custom dropdown names
var createContainerNames = function () {
function Names() {
this.id = "Tasks_" + dynamicCounter + "__ContainerId";
this.name = "Tasks[" + dynamicCounter + "].ContainerId";
this.parent = "task" + dynamicCounter + "Container";
}
Names.prototype = { constructor: Names };
return function () { return new Names(); };
} ();
And then I use it:
var createdNames = createContainerNames();
var createdId = createdNames.id;
dynamicCounter++;
var differentNames = createContainerNames();
var differentId = differentNames.id;
Another approach would be to do this:
var NameModule = function(){
//"private" namemodule variables
var priv1 = "Hello";
//"private namemodule methods
function privMethod1(){
//TODO: implement
}
//"public namemodule variables
var pub1 = "Welcome";
//"public" namemodule methods
function PubMethod(){
//TODO: pub
}
return {
pub1 : pub1,
PubMethod: PubMethod
};
and then to use it
var myPubMethod = new NameModule();
myPubMethod.PubMethod();
var pubVar = myPubMethod.pub1;
EDIT
You could also take this approach:
var mod = function(){
this.modArray = [];
};
mod.prototype = {
//private variables
modId: null,
//public method
AddToArray: function (obj) {
this.modArray.push(obj);
}
}

Categories

Resources