Promise not getting resolved - javascript

I have problem when calling promise from PO. In PO it works OK but in main test page it gives undefined value. Like function on main page is called before promise is resolved
PO code
this.Email = function (){
this.userIcon.getText(this.userIcon).then(function (text){
this.email=text.slice(5);
console.log(this.email);
return this.email
});
Code in main test page
email = data.Email();
Sorry here is the whole code from PO
var data = function(){
this.user = 'baseer#adnoc.ae';
this.pass = '123123';
this.usrform = element(by.css("input[formControlName=username]"));
this.passinput = element(by.css("input[formControlName=password]"));
this.button = element(by.tagName('button'));
this.text = 'Something smart'
this.dir=Math.floor((Math.random() * 3) + 1);
this.subID;
this.dropdown = element.all(by.css("mat-option"));
this.datepicker = element.all(by.xpath("//mat-datepicker-toggle[#class='mat-datepicker-toggle']"));
this.calendar = element(by.xpath("//div[#class='mat-calendar-header']"));
this.calendar = element(by.xpath("//tbody[#class='mat-calendar-body']"));
this.routeArea;
this.countryOfOrigin = element(by.xpath("//mat-select[contains(#formcontrolname,'countryOfOriginId')]"));
this.countryList = element(by.xpath("//div[#class='select-option-cont']"))
this.userProfileRoute = element(by.xpath("//mat-select[contains(#formcontrolname,'assignToUserProfileId')]"));
this.userIcon=element(by.xpath("//a[#class='mat-menu-item']"));
this.Email = function (){
this.userIcon.getText(this.userIcon).then(function (text){
this.email=text.slice(5);
console.log(this.email);
return this.email
});
};`enter code here`
};
module.exports = new data();

Your code should have been
this.Email = function (){
return this.userIcon.getText(this.userIcon).then(function (text){
this.email=text.slice(5);
console.log(this.email);
return this.email
});
Here is why - if you don't return a value from a function you can't reuse it
let my_func = function (a, b) {
let some_var = a + b
}
let result = my_func(1,2);
console.log(result) // undefined
because you're missing return statement, so if you do
let my_func = function (a, b) {
let some_var = a + b
return some_var
}
let result = my_func(1,2);
console.log(result) // 3
The same happens if you do nested functions
let my_func_one = function (a, b) {
let some_var = a + b
return
}
let my_func_two = (a,b) {
my_func_one(a,b)
}
let result = my_func_two(1,2);
console.log(result) // undefined
that happens because your outer function doesn't return anything, but simply runs inner function. But if you have
let my_func_one = function (a, b) {
let some_var = a + b
return some_var
}
let my_func_two = (a,b) {
return my_func_one(a,b) // return
}
let result = my_func_two(1,2);
console.log(result) // 3

Related

Get return value of worker.onmessage inside a function?

I have created a Caching (Memoized) function which takes another function as a parameter
The following is the function which is being cached. The function utilises a worker. The issue here is that if
var hello = GetSubRegion(1233) ,then hello is undefined because the function inside onmessage returns a value but not the parent GetSubRegion function.
function GetSubRegion(selectedMainRegion){
if (typeof(subRegWorker) != "undefined") {
subRegWorker.terminate();
}
subRegWorker = new Worker("subRegWorker.js");
subRegWorker.onmessage = function(e) {
var workData = e.data;
jQuery("#_sub_region").html(workData);
subRegWorker.terminate();
return workData;
}
var result = subRegWorker.postMessage(selectedMainRegion);
return result;
}
The following is the caching function. Due to the above issue, there is no value returned for let result = fun(n) , and hence nothing is cached.
function memoizer(fun){
let cache = {}
return function (n){
if (cache[n] != undefined ) {
return cache[n]
} else {
console.log(n);
let result = fun(n)
cache[n] = result
return result
}
}
}
How to solve this ?
The following is how I am calling the cached function.
jQuery("#_main_region").change(function() {
var getCacheSub = memoizer(GetSubRegion);
var inputMainRegion = jQuery('#_main_region').find(":selected").val();
getCacheSub(inputMainRegion);
});
The caching issue was solved as follows, the changed code is market as comment -
var cache = {};
function memoizer(fun){
return function (n){
if (cache[n] != undefined ) {
jQuery("#_sub_region").html(cache[n]); // This was changed
return cache[n]
} else {
console.log(n);
cache[n] = result
return result
}
}
}
function GetSubRegion(selectedMainRegion){
if (typeof(subRegWorker) != "undefined") {
subRegWorker.terminate();
}
subRegWorker = new Worker("subRegWorker.js");
subRegWorker.onmessage = function(e) {
var workData = e.data;
cache[n] = workData // This was changed
jQuery("#_sub_region").html(workData);
subRegWorker.terminate();
return workData;
}
subRegWorker.postMessage(selectedMainRegion);
}

In the javascript, is this function pure

function add() {
var args = [].slice.call(arguments);
var fn = function() {
var fn_args = [].slice.call(arguments)
return add.apply(null, args.concat(fn_args))
}
fn.toString = function() {
return '' + args.reduce(function(acc, prev){
return acc + prev
})
}
return fn;
}
I don't sure if this function is pure.
because I can change the result externally;
var result = add(1);
result.toString = () => 'hello';

Passing Arguments to function in javascript

I have a function(case) as below,
let fn = (() => {
let ab = {};
let register = () => {
console.log("hello" + ab[x])
};
return (x,y) => {
ab[x] = y;
return register();
};
})();
this function is working only when I call as below,
let x = 'key';
let y = 'value';
fn(x,y);
Is there any chance to call directly like
fn('key', 'value');
what changes I have to make in function to call directly
The problem is your register function doesn't know about x. You need to pass it through from your previous function:
let fn = (() => {
let ab = {};
let register = (x) => {
console.log("hello" + ab[x])
};
return (x,y) => {
ab[x] = y;
return register(x);
};
})();
fn("key", "value");
I believe this is because you aren’t defining the parameters in the functions.
let fn = ((x,y) => {
let ab = {};
let register = () => {
console.log("hello"+ab[x])};
return (x,y) => {
ab[x]=y;
return register();
};
})();

method chaining failed in javascript

I'm trying to train myself to write chaining function but got error of
Cannot read property 'minus' of undefined(…)
What's wrong with my code?
var math = function(){
var result = 0;
var add = function(param){
result += param;
};
var minus = function(param){
result -= param;
};
var print = function(){
console.log(result)
};
return {add:add, minus: minus, print:print};
}
var calculator = math();
var result = calculator.add(5).minus(1).print();
console.log(result)
You need to return the object (this) in this case, to "chain" like you are expecting
You print() also doesn't return anything so result is always undefined.
var math = function(){
var result = 0;
var add = function(param){
result += param;
return this;
};
var minus = function(param){
result -= param;
return this;
};
var print = function(){
console.log('result: ' + result);
// print doesnt return anything, it needs to if you want to assign anything by calling it
return result;
};
return {add:add, minus: minus, print:print};
}
var calculator = math();
var result = calculator.add(5).minus(1).print();
console.log(result)
You can also store a reference to the object returned.
var math = function() {
var result = 0;
var add = function(param) {
result += param;
return math;
};
var minus = function(param) {
result -= param;
return math;
};
var print = function() {
console.log(result)
};
var math = {
add: add,
minus: minus,
print: print
};
return math;
}
var calculator = math();
calculator.add(5).minus(1).print();

Javascript and module pattern

i think i did not understand javascript module pattern.
I just create this module:
var mycompany = {};
mycompany.mymodule = (function() {
var my = {};
var count = 0;
my.init = function(value) {
_setCount(value);
}
// private functions
var _setCount = function(newValue) {
count = newValue;
}
var _getCount = function() {
return count;
}
my.incrementCount = function() {
_setCount(_getCount() + 1);
}
my.degreeseCount = function() {
_setCount(_getCount() - 1);
}
my.status = function() {
return count;
}
return my;
})();
var a = mycompany.mymodule;
var b = mycompany.mymodule;
console.debug(a, 'A at beginning');
console.debug(a, 'B at beginning');
a.init(5);
b.init(2);
console.log('A: ' + a.status()); // return 2 (wtf!)
console.log('B: ' + b.status()); // return 2`
Where is the mistake?
I thought that my code would have returned to me not 2 value, but 5.
What's the reason?
a and b are the exact same objects.
var a = mycompany.mymodule;
var b = mycompany.mymodule;
What you want to do is create two different objects which have the same prototype. Something similar to this:
mycompany.mymodule = (function () {
var my = function () {};
my.prototype.init = function (value) {
_setCount(value);
};
my.prototype.incrementCount = ...
// ...
return my;
}());
a = new mycompany.mymodule();
b = new mycompany.mymodule();
a.init(5);
b.init(2);
For more info, research "javascript prototypal inheritance"
In JavaScript, objects are passed by reference, not copied.
To explain further, here is a simplified version of your code:
var pkg = (function () {
var x = {};
return x;
}());
var a = pkg;
var b = pkg;
You do not create two separate objects but only reference the object pointed at by pkg from both a and b. a and b are exactly the same.
a === b // true
This means that calling a method on a you are ultimately doing the same to b (it points to the same object—x.)
You don't want to use the module pattern for this. You want the usual constructor+prototype.
function Pkg() {
this.count = 0;
};
Pkg.prototype.init = function (count) { this.count = count; };
var a = new Pkg();
var b = new Pkg();
a === b // false
a.init(2);
a.count === 2 // true
b.count === 2 // false
Here is a good read about module pattern.

Categories

Resources