Need an explanation on simple code - javascript

$('#ID').on('click', function() {
if(!CommonUtil.compareDateById('startDt','endDt',false, false, true)) {
return false;
}
var cnt = 0;
if(!CommonUtil.isNullOrEmptyById('startDt')) { cnt++; }
if(cnt == 0) {
CommonUtil.setFocusById('srchWord','<spring:message code="confirm.input" arguments="XXXX"/>');
return false;
So if I click on #ID, following logic occurs.
And my question is what does
var cnt = 0;
if(!CommonUtil.isNullOrEmptyById('startDt')) {
cnt++;
}
mean?
The function of isNullOrEmptyById is following:
isNullOrEmptyById: function(id) {
var value = this.getTrimValueById(id);
return this.isNullOrEmpty(value);
},
But what does
cnt++;
do in here??

This is just an if conditional block:
if(!CommonUtil.isNullOrEmptyById('startDt')) {
cnt++;
}
So if CommonUtil.isNullOrEmptyById('startDt') resolves to false, then the condition resolves to true and the code in the block is executed:
cnt++;
The ++ operator increments the value. So whatever numeric value is in cnt will be incremented by 1.
In the overall context of the code, it seems to be treating cnt as more of a boolean than an integer, though. Unless there's more code outside of this example, this can be simplified by using this condition for the last conditional block instead of using cnt and then checking its value.

It is actually unnecessary. Since the cnt is only incremented once it's value is either 0 or 1. Instead you could just get rid of all that and use isNullOrEmptyById function.
if(!CommonUtil.isNullOrEmptyById('startDt')){
CommonUtil.setFocusById('srchWord','<spring:message code="confirm.input" arguments="XXXX"/>');
return false;
}

Related

Difference between JQuery $.each loop and JS for loop [duplicate]

I want to return false and return from function if I find first blank textbox
function validate(){
$('input[type=text]').each(function(){
if($(this).val() == "")
return false;
});
}
and above code is not working for me :(
can anybody help?
You are jumping out, but from the inner loop, I would instead use a selector for your specific "no value" check, like this:
function validate(){
if($('input[type=text][value=""]').length) return false;
}
Or, set the result as you go inside the loop, and return that result from the outer loop:
function validate() {
var valid = true;
$('input[type=text]').each(function(){
if($(this).val() == "") //or a more complex check here
return valid = false;
});
return valid;
}
You can do it like this:
function validate(){
var rv = true;
$('input[type=text]').each(function(){
if($(this).val() == "") {
rv = false; // Set flag
return false; // Stop iterating
}
});
return rv;
}
That assumes you want to return true if you don't find it.
You may find that this is one of those sitautions where you don't want to use each at all:
function validate(){
var inputs = $('input[type=text]');
var index;
while (index = inputs.length - 1; index >= 0; --index) {
if (inputs[index].value == "") { // Or $(inputs[index]).val() == "" if you prefer
return false;
}
}
// (Presumably return something here, though you weren't in your example)
}
I want to add something to existing answers to clear the behavior of $(selector).each and why it doesn't respect return false in OP's code.
return keyword inside $(selector).each is used to break or continue the loop. If you use return false, it is equivalent to a break statement inside a for/while loop. Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration. Source
Because you're returning false, the loop breaks and the function ends up returning undefined in your case.
Your option is to use a var outside $.each or avoid using it altogether as #TJCrowder wrote.

break from while loop from anonymous function

I am new to javascript, my background is python and ruby and I am having issues dealing with javascript anonymous functions, my problem is the following:
I have an element in the page which has an attribute value (true/false), I need to keep performing an action until this attribute changes value.
the code that I tried out is below, as you could guess, the break won't quit the loop if result.value == true... Any idea if I am in the right direction?
var counter = 0;
while (counter < 5) {
this
.click('#someelementid')
counter++;
this
.getAttribute('#someelementid', 'disabled', function(result) {
if (result.value == 'true') {
this.break;
}
}.bind(this));
this.api.pause(1000);
};
My assumption is that by binding this, I have access to the while block? Please correct me if I am wrong.
Have you tried changing your code to something like below ?
var counter = 0;
var arr = [1, 2, 3, 4, 5];
while (counter < 5) {
arr.forEach(
(element) => {
if (counter < 5) { // if you don't have this it will print all 5, else it prints only 3
console.log('Element value:', element);
}
if (element == 3) {
counter = 5;
}
}
);
}
What happens is this:
When you enter the while loop it will enter the forEach loop and start iterating, when it reaches element == 3 it will set counter to 5, but it still has to finish the current forEach loop, once it does it wont perform another while loop therefore exiting it.
So changing your code to:
var counter = 0;
while (counter < 5) {
this
.click('#someelementid')
counter++;
this
.getAttribute('#someelementid', 'disabled', function(result) {
if (result.value == 'true') {
counter = 5; // This should do the trick (without 'this')
}
}.bind(this));
this.api.pause(1000);
};
The break inside a function would not break the loop outside the function.
Through getAttribute() get the result inline instead of having a callback. then you can break the function.
Or
Have a global variable. breakLoop = false; set it to true; inside the callback function. And put a check on this variable in the while loop. while(!breakLoop ..)
Another approach.
Don't have a loop altogether.
var counter = 0;
function doSomething(){
this.click('#someelementid');
counter++;
this.getAttribute('#someelementid', 'disabled', function(result) {
if(result.value != 'true' && counter<5){
this.api.pause(1000);
doSomething();
}
}.bind(this);
};

how to check the presence of the element in the array?

please help solve the problem.
live example is here: https://jsfiddle.net/oqc5Lw73/
i generate several tank objects:
var Tank = function(id) {
this.id = id;
Tank.tanks.push(this);
}
Tank.tanks = [];
for (var i = 0; i < 3; i++) {
new Tank(i);
}
Tank.tanks.forEach(function(tank, i, arr) {
console.log(tank);
});
console.log('summary tanks: ' + Tank.tanks.length);
after i delete tank with random index:
var tankDel = Math.floor(Math.random() * (3));
Tank.tanks.splice(tankDel, 1);
Tank.count -= 1;
Tank.tanks.forEach(function(tank, i, arr) {
console.log(tank);
});
console.log('summary tanks: ' + Tank.tanks.length);
i try check tanks massive. if tanks massive contain tank with property 'id' = 0 then i need display alert('tank with id 0 is dead').
but console output follow error message:
Uncaught SyntaxError: Illegal break statement
break is to break out of a loop like for, while, switch etc which you don't have here, you need to use return to break the execution flow of the current function and return to the caller. See similar post here: illegal use of break statement; javascript
Tank.tanks.forEach(function(tank, i, arr) {
if(tank.id == 0) {
tank0Dead = false;
return;
};
});
if(tank0Dead == true) {
alert('tank with id 0 is dead');
};
jsfiddle : https://jsfiddle.net/oqc5Lw73/6/
You can't quit from forEach using break. Just remove break, and it will work.
P.S: honestly, it is better to refactor that code:)
Your only problem is that you can't use the break; statement in a forEach function.
But you can in a for() loop, so here is the equivalent code with a for :
for (var i = 0; i < Tank.tanks.length; i++){
if (Tank.tanks[i].id == 0){
tank0Dead = false;
break;
}
}
https://jsfiddle.net/oqc5Lw73/5/
But I agree with #dimko1 about the idea of refactoring the code
You can not break a forEach callback, simply because it's a function.
Here's updated working jSfiddle
If you really want to break it, you can use exception like code below.
try {
[1,2,3].forEach(function () {
if(conditionMet) {
throw Error("breaking forEach");
}
});
} catch(e) {
}
Otherwise you can use jQuery's each() method. when it's callback returns false it stops.
jQuery.each([1,2,3], function () {
if(conditionMet) {
return false;
}
});

need help using for loop and getText() in protractor

browser.findElements(protractor.By.repeater('cat in cats')).then(function(rows) {
for (i = 0; i < rows.length; i++) { //which is always 3
var tmp = element(by.repeater('cat in cats').row(i)).element(by.binding('cat.name')).getText();
tmp.then(function(text) {
console.log('text is : ' + text);
console.log('iteration number is: ' + i);
if (text == 'someText') {
element(by.repeater('cat in cats').row(i)).element(by.binding('cat.action')).click();
}
});
}
In this case the value of 'i' inside the function is always returning 3.
I have get text and then check if the text is what I want and click on an element.
The value of 'i' in the 'if' statement is always returned as 3. Something to do with promises, but I am not sure.
Any help with modified code is much appreciated.
Thanks!
Don't call by.repeater() multiple times; instead, use map() and "chain" the promises like this:
element.all(By.repeater('cat in cats')).map(function(elm) {
return {
text: elm.element(by.binding('cat.name')).getText(),
action: elm.element(by.binding('cat.action'))
};
}).then(function(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i].text == 'someText') {
return arr[i].action;
}
}
throw new Error('Text not found');
}).then(function(elm) {
elm.click();
});
All of the credits go to #Andres for the solution provided here:
Passing Protractor ElementFinder to deferred.fulfill() results in a promise containing a null value
Also see:
Protractor find element inside a repeater

Asyncronous variables outside a for loop

I'm just starting out with AJAX and I'm trying to get a variable to be set inside a for loop. Then I want to call that variable later and use it's value.
Of course this would be synchronous, requiring the scripts to stop executing in order to run the loop before returning the new value of the function.
I'm hoping someone knows a better way to get the value from the for loop AFTER the for loop has run and use it in my code directly after that.
I would prefer not to use the setTimeout() hack to bypass this issue (it is a hack after all).
var getCount = function getCount(res) {
count = { active: 0, closed: 0 }; //Variable defined here
for(i=0; i<=res.length; i++) {
if(res[i].status == 'active') {
count.active ++;
} else { count.closed ++; }
}
return count; //And returned here
};
getCount(result);
console.log(count); //Here's where I need the result of the for loop
//Currently this outputs the count object with both properties set to 0;
I am not sure what AJAX has to do with your issue.
You are not assigning the result of the getCount function to the count variable (Unless you intended the count variable to be global, but in that case you need to define it before the getCount function definition).
Change this line:
getCount(result);
to this:
var count = getCount(result);
And you should be alright. :)
I would also suggest, when declaring variables, always declare them with var. In your case:
var count = { active: 0, closed: 0};
I don't know why you mention AJAX since there is nothing async about your code.
From what I see in your sample I don't see what all the difficulty is about.
Just use it as any other function.
function getCount(res) {
var count = { active: 0, closed: 0 }; //Variable defined here
for(i=0; i<=res.length; i++) {
if(res[i].status == 'active') {
count.active ++;
} else { count.closed ++; }
}
return count; //And returned here
};
console.log(getCount(result)); //Here's where I need the result of the for loop
First off, you had an extra = sign that was over-extending your for loop. I don't know if this answers your asynchronous issue, but here is how I would do it:
// sample object
var result = [
{status:"active"},
{status:"not-active"},
{status:"active"}
];
// kick off the function to get the count object back
var counts = getCount(result);
console.log(counts);
function getCount(res) {
var count = { active: 0, closed: 0 }; //Variable defined here, make sure you have var to keep it from going global scope
for(i=0; i<res.length; i++) { //here you had a wrong "="
if(res[i].status === 'active') {
count.active ++;
} else { count.closed ++; }
}
return count; //And returned here
}
Example here.

Categories

Resources