Google Appscript IF Or statement not working - google-apps-script

Good day everyone; I am running into an error I can't explain. The scenario is as follows, I have two input boxes that collect information. If no value is entered, I want the if statement to handle it and cause a break. The Input box also has an "x" to close the box, which returns a value of "Cancel". What I am trying to do is capture a condition where if no value is entered OR cancel is passed through, a break will occur. Right now, the problem is Google completely ignores the Or statement. I know individually, my IF logic works, but when coupled with OR it doesn't recognize the condition.
This is my current code:
var propnumber = Browser.inputBox('Enter RFI/RFQ Number', Browser.Buttons.OK);
if(propnumber != "" || propnumber != 'cancel'){} else{
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
};
var myName = Browser.inputBox("Enter the Component Name",Browser.Buttons.OK_CANCEL);
if(myName != 'cancel')
{
I do something
}
As I mentioned in my description, my propnumber condition ignores the or and always accepts the value of cancel or blank. If I remove the or ( || ) then it works with one condition at a time.
I am sure this is something trivial any help appreciated.

What's wrong
The logic in the following part of your code
if(propnumber != "" || propnumber != 'cancel'){
// I assume some code will go here
} else{
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
};
does not match the logic you've described here:
if no value is entered OR cancel is passed through, a break will occur.
Consider the case where propnumber is 'cancel':
propnumber != "" evaluates to true
propnumber != 'cancel' evaluates to false
Therefore the if(... || ...) condition in your code evaluates to true and the (currently empty) if block runs, rather than the else.
How to fix it
Option 1: A literal translation of the logic
if no value is entered OR cancel is passed through, a break will occur
would be
if(propnumber == "" || propnumber == 'cancel') {
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
} else {
// Some action
}
Option 2: If you wish to swap the if and else clauses, you must negate the entire condition. So this will also work:
if(!(propnumber == "" || propnumber == 'cancel')) {
// Some action
} else {
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
}
Note the added parentheses and single negation.
Option 3: use AND instead of OR in your existing code.
The expression !(A || B) is NOT logically equivalent to !A || !B. Instead, it is equivalent to !A && !B (see DeMorgan's Law). So this will also work:
if(propnumber != "" && propnumber != 'cancel') {
// Some action
} else {
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
}

Related

Google Script - if criteria met run certain functions else do nothing

I have the below script with the purpose of retrieving the value in the google sheet which will either state TRUE or FALSE. If it states false I want this script to run the two functions below (updateWIPdata and updateDebtorsdata) but if the cell value is true I don't want those functions to run at all but the functions seem to run regardless of the value in the cell so any help would be much appreciated
function updateAll() {
var updateStatus = SpreadsheetApp.getActive().getSheetByName('Updated').getRange('C2').getValue();
Logger.log(updateStatus);
if (updateStatus = 'false') {
updateWIPdata();
updateDebtorsdata();
}
}
Probably the value is a boolean.
Also, please use == or ===
if (updateStatus == false) {
Reference:
Equality operators
The fix is simple
But you also want to improve a few things in your code
The main problem is in this line:
if (updateStatus = 'false')
You are not comparing updateStatus to false, you are assigning 'false' to updateStatus. On top of that you are assigning a string, not a boolean. The line needs to be
if (false === updateStatus)
Notice three things:
false is a boolean here, it doesn't have quotation marks around it
It's on the left side of the comparison; putting litteral values on the left side is a habbit that prevents this type of error
I'm using the === comparison operator instead of the = assignment operator
Another thing you need to do is forget about var and start using const and let. If your updateStatus was a const, you would have very quickly realized the error.

if condition cannot catch the null value of my front end username field in javascript and html

I have a username text field in the login.html file.
I have javascript code as follows
loginbtn.addEventListener("click", function() {
if(username.value != null) {
socket.emit("login", {username:username.value});
$("#name").hide();
$("#mario-chat").show();
} else {
err.innerHTML = document.write("please enter username");
}
});
In the login page i have not entered any name but still my code goes to the if condition and executing the 1$("#name").hide();$("#mario-chat").show();.
Please tell me why my if condition is executing rather than else part. thanks in advance.
If you console.log(username.value) the result will probably not be null or undefined. That is why != null does not the trick.
username.value might be an empty string so you can add && username.value != '' to the if statement. if(username.value != null && username.value != ''){}

Extra "Space" at end of "If" Requirement AS3

My code works, except it is requiring and extra "Space" at the end to be placed in order for the button to activate? Any ideas? I obviously don't have the space at the end of the user names or passwords in the code. This happens on another frame as well where I have the user type in a web address, I have the conditional set as == "md.website.com" but it is requiring "md.website.com " (extra space at the end) in order for the button to activate.
This code is expecting "AB1234 " and "newuser " instead of "AB1234" "newuser" like I need and I am telling it... I'm sorry, I'm new to AS3 and learning ALL I can, this site rocks for all the help I've already gotten!
username_txt.addEventListener(TextEvent.TEXT_INPUT,paramChanged3);
password_txt.addEventListener(TextEvent.TEXT_INPUT,paramChanged3);
next_btn.enabled = false;
next_btn.alpha = .5;
function paramChanged3(event:TextEvent):void
{
if (username_txt.text == "AB1234" && password_txt.text == "newuser" )
{
trace("go")
next_btn2.enabled = true;
next_btn2.alpha = 1;
next_btn2.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndPlay_20)
}
else
{
next_btn2.enabled = false;
next_btn2.alpha = .5;
}
}
function fl_ClickToGoToAndPlay_20(event:MouseEvent):void
{
gotoAndPlay(20);
}
The problem is that the TextEvent.TEXT_INPUT fires before the text field is actually updated. Try using Event.CHANGE instead (or using two TextEvent.TEXT_INPUT callbacks and appending the input character with event.text within each).
I don't know why AS3 is requiring the extra space, but I removed the exact conditional, and just did a minimum character count. Of course the trainee can then type in anything as long as it matches the minimum requirement, but again, the actual usernames and passwords don't matter, its all simulation anyways, here is the code with the character count....
username_txt.addEventListener(TextEvent.TEXT_INPUT,paramChanged3);
password_txt.addEventListener(TextEvent.TEXT_INPUT,paramChanged3);
next_btn.enabled = false;
next_btn.alpha = .5;
function paramChanged3(event:TextEvent):void
{
if (username_txt.text != "" && username_txt.length >=5 &&
password_txt.text != "" && password_txt.length >=6)
{
trace("go")
next_btn2.enabled = true;
next_btn2.alpha = 1;
next_btn2.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndPlay_20)
}
else
{
next_btn2.enabled = false;
next_btn2.alpha = .5;
}
}
function fl_ClickToGoToAndPlay_20(event:MouseEvent):void
{
gotoAndPlay(20);
}

if-check in HTML gone awry

I wrote a short function to do some error checks for a form and am stuck at a portion of code where the final 'elseif' clause in the code below keeps getting executed, even when there is text in the textbox...
could you please advise...thank you..
function errorCheck(){
if(!isInteger(document.getElementById("appleQty").value)){
alert('Please key in an integer in the Apple Quantity text box.');
document.getElementById("appleQty").value="";
document.getElementById("appleQty").focus();
return false;
}
else if(!isInteger(document.getElementById("orangeQty").value)){
alert('Please key in an integer in the Orange Quantity text box.');
document.getElementById("orangeQty").value="";
document.getElementById("orangeQty").focus();
return false;
}
else if(!isInteger(document.getElementById("bananaQty").value)){
alert('Please key in an integer in the Banana Quantity text box.');
document.getElementById("bananaQty").value="";
document.getElementById("bananaQty").focus();
return false;
}
else if(document.getElementById("user").value = " "){ /!-Problem, keeps getting repeated-->
document.getElementById("user").focus();
alert('Please key in your name.');
return false;
}
return true;
}
One should use == to compare, = to assign. You are assigning, so add an extra = to compare.
You are using = as assignment, not equivalence. Use == or ===.
Two problems:
Use == for comparison, not =.
The empty string is "", not " ". Notice the extra space.
Result:
else if (document.getElementById("user").value == "") {

How do you handle huge if-conditions?

It's something that's bugged me in every language I've used, I have an if statement but the conditional part has so many checks that I have to split it over multiple lines, use a nested if statement or just accept that it's ugly and move on with my life.
Are there any other methods that you've found that might be of use to me and anybody else that's hit the same problem?
Example, all on one line:
if (var1 = true && var2 = true && var2 = true && var3 = true && var4 = true && var5 = true && var6 = true)
{
Example, multi-line:
if (var1 = true && var2 = true && var2 = true
&& var3 = true && var4 = true && var5 = true
&& var6 = true)
{
Example-nested:
if (var1 = true && var2 = true && var2 = true && var3 = true)
{
if (var4 = true && var5 = true && var6 = true)
{
Separate the condition in several booleans and then use a master boolean as the condition.
bool isOpaque = object.Alpha == 1.0f;
bool isDrawable = object.CanDraw && object.Layer == currentLayer;
bool isHidden = hideList.Find(object);
bool isVisible = isOpaque && isDrawable && ! isHidden;
if(isVisible)
{
// ...
}
Better yet:
public bool IsVisible {
get
{
bool isOpaque = object.Alpha == 1.0f;
bool isDrawable = object.CanDraw && object.Layer == currentLayer;
bool isHidden = hideList.Find(object);
return isOpaque && isDrawable && ! isHidden;
}
}
void Draw()
{
if(IsVisible)
{
// ...
}
}
Make sure you give your variables name that actualy indicate intention rather than function. This will greatly help the developer maintaining your code... it could be YOU!
I'm surprised no one got this one yet. There's a refactoring specifically for this type of problem:
http://www.refactoring.com/catalog/decomposeConditional.html
There are two issues to address here: readability and understandability
The "readability" solution is a style issue and as such is open to interpretation. My preference is this:
if (var1 == true && // Explanation of the check
var2 == true && // Explanation of the check
var3 == true && // Explanation of the check
var4 == true && // Explanation of the check
var5 == true && // Explanation of the check
var6 == true) // Explanation of the check
{ }
or this:
if (var1 && // Explanation of the check
var2 && // Explanation of the check
var3 && // Explanation of the check
var4 && // Explanation of the check
var5 && // Explanation of the check
var6) // Explanation of the check
{ }
That said, this kind of complex check can be quite difficult to mentally parse while scanning the code (especially if you are not the original author). Consider creating a helper method to abstract some of the complexity away:
/// <Summary>
/// Tests whether all the conditions are appropriately met
/// </Summary>
private bool AreAllConditionsMet (
bool var1,
bool var2,
bool var3,
bool var4,
bool var5,
bool var6)
{
return (
var1 && // Explanation of the check
var2 && // Explanation of the check
var3 && // Explanation of the check
var4 && // Explanation of the check
var5 && // Explanation of the check
var6); // Explanation of the check
}
private void SomeMethod()
{
// Do some stuff (including declare the required variables)
if (AreAllConditionsMet (var1, var2, var3, var4, var5, var6))
{
// Do something
}
}
Now when visually scanning the "SomeMethod" method, the actual complexity of the test logic is hidden but the semantic meaning is preserved for humans to understand at a high-level. If the developer really needs to understand the details, the AreAllConditionsMet method can be examined.
This is formally known as the "Decompose Conditional" refactoring pattern I think. Tools like Resharper or Refactor Pro! can making doing this kind of refactoring easy!
In all cases, the key to having readable and understandable code is to use realistic variable names. While I understand this is a contrived example, "var1", "var2", etc are not acceptable variable names. They should have a name which reflects the underlying nature of the data they represent.
I'll often split these up into component boolean variables:
bool orderValid = orderDate < DateTime.Now && orderStatus != Status.Canceled;
bool custValid = customerBalance == 0 && customerName != "Mike";
if (orderValid && custValid)
{
...
First, I'd remove all the == true parts, that would make it 50% shorter ;)
When I have big condition I search for the reasons. Sometimes I see I should use polymorphism, sometimes I need to add some state object. Basically, it implies a refactoring is needed (a code smell).
Sometimes I use De-Morgan's laws to simplify boolean expressions a bit.
Check out Implementation Patterns by Kent Beck. There is a particular pattern I am thinking of that may help in this situation... it is called "Guards". Rather than having tons of conditions, you can break them out into a guard, which makes it clear which are the adverse conditions in a method.
So for example, if you have a method that does something, but there are certain conditions where it shouldn't do something, rather than:
public void doSomething() {
if (condition1 && condition2 && condition3 && condition4) {
// do something
}
}
You could change it to:
public void doSomething() {
if (!condition1) {
return;
}
if (!condition2) {
return;
}
if (!condition3) {
return;
}
if (!condition4) {
return;
}
// do something
}
It's a bit more verbose, but a lot more readable, especially when you start having weird nesting, the guard can help (combined with extracting methods).
I HIGHLY recommend that book by the way.
I've seen a lot of people and editors either indenting each condition in your if statement with one tab, or matching it up with the open paren:
if (var1 == true
&& var2 == true
&& var3 == true
) {
/* do something.. */
}
I usually put the close paren on the same line as the last condition:
if (var1 == true
&& var2 == true
&& var3 == true) {
/* do something.. */
}
But I don't think this is quite as clean.
Steve Mcconell's advice, from Code Complete:
Use a multi-dimensional table. Each variable serves as an index to the table,
and the if statement turns into a table lookup. For example if (size == 3 && weight > 70)
translates into the table entry decision[size][weight_group]
Try looking at Functors and Predicates. The Apache Commons project has a great set of objects to allow you to encapsulate conditional logic into objects. Example of their use is available on O'reilly here. Excerpt of code example:
import org.apache.commons.collections.ClosureUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.functors.NOPClosure;
Map predicateMap = new HashMap();
predicateMap.put( isHonorRoll, addToHonorRoll );
predicateMap.put( isProblem, flagForAttention );
predicateMap.put( null, ClosureUtils.nopClosure() );
Closure processStudents =
ClosureUtils.switchClosure( predicateMap );
CollectionUtils.forAllDo( allStudents, processStudents );
Now the details of all those isHonorRoll predicates and the closures used to evaluate them:
import org.apache.commons.collections.Closure;
import org.apache.commons.collections.Predicate;
// Anonymous Predicate that decides if a student
// has made the honor roll.
Predicate isHonorRoll = new Predicate() {
public boolean evaluate(Object object) {
Student s = (Student) object;
return( ( s.getGrade().equals( "A" ) ) ||
( s.getGrade().equals( "B" ) &&
s.getAttendance() == PERFECT ) );
}
};
// Anonymous Predicate that decides if a student
// has a problem.
Predicate isProblem = new Predicate() {
public boolean evaluate(Object object) {
Student s = (Student) object;
return ( ( s.getGrade().equals( "D" ) ||
s.getGrade().equals( "F" ) ) ||
s.getStatus() == SUSPENDED );
}
};
// Anonymous Closure that adds a student to the
// honor roll
Closure addToHonorRoll = new Closure() {
public void execute(Object object) {
Student s = (Student) object;
// Add an award to student record
s.addAward( "honor roll", 2005 );
Database.saveStudent( s );
}
};
// Anonymous Closure flags a student for attention
Closure flagForAttention = new Closure() {
public void execute(Object object) {
Student s = (Student) object;
// Flag student for special attention
s.addNote( "talk to student", 2005 );
s.addNote( "meeting with parents", 2005 );
Database.saveStudent( s );
}
};
Well, first off, why not:
if (var1 && var2 && var2 && var3 && var4 && var5 && var6) {
...
Also, it's very hard to refactor abstract code examples. If you showed a specific example it would be easier to identify a better pattern to fit the problem.
It's no better, but what I've done in the past:
(The following method prevents short-circuiting boolean testing, all tests are run even if the first is false. Not a recommended pattern unless you know you need to always execute all the code before returning -- Thanks to ptomato for spotting my mistake!)
boolean ok = cond1;
ok &= cond2;
ok &= cond3;
ok &= cond4;
ok &= cond5;
ok &= cond6;
Which is the same as: (not the same, see above note!)
ok = (cond1 && cond2 && cond3 && cond4 && cond5 && cond6);
I resort to separate boolean values:
Bool cond1 == (var1 && var2);
Bool cond2 == (var3 && var4);
if ( cond1 && cond2 ) {}
As others have mentioned, I would analyze your conditionals to see if there's a way you can outsource it to other methods to increase readability.
In reflective languages like PHP, you can use variable-variables:
$vars = array('var1', 'var2', ... etc.);
foreach ($vars as $v)
if ($$v == true) {
// do something
break;
}
I like to break them down by level, so I'd format you example like this:
if (var1 = true
&& var2 = true
&& var2 = true
&& var3 = true
&& var4 = true
&& var5 = true
&& var6 = true){
It's handy when you have more nesting, like this (obviously the real conditions would be more interesting than "= true" for everything):
if ((var1 = true && var2 = true)
&& ((var2 = true && var3 = true)
&& (var4 = true && var5 = true))
&& (var6 = true)){
If you happen to be programming in Python, it's a cinch with the built-in all() function applied over the list of your variables (I'll just use Boolean literals here):
>>> L = [True, True, True, False, True]
>>> all(L) # True, only if all elements of L are True.
False
>>> any(L) # True, if any elements of L are True.
True
Is there any corresponding function in your language (C#? Java?). If so, that's likely the cleanest approach.
McDowell,
You are correct that when using the single '&' operator that both sides of the expression evaluate. However, when using the '&&' operator (at least in C#) then the first expression to return false is the last expression evaluated. This makes putting the evaulation before the FOR statement just as good as any other way of doing it.
#tweakt
It's no better, but what I've done in the past:
boolean ok = cond1;
ok &= cond2;
ok &= cond3;
ok &= cond4;
ok &= cond5;
ok &= cond6;
Which is the same as:
ok = (cond1 && cond2 && cond3 && cond4 && cond5 && cond6);
Actually, these two things are not the same in most languages. The second expression will typically stop being evaluated as soon as one of the conditions is false, which can be a big performance improvement if evaluating the conditions is expensive.
For readability, I personally prefer Mike Stone's proposal above. It's easy to verbosely comment and preserves all of the computational advantages of being able to early out. You can also do the same technique inline in a function if it'd confuse the organization of your code to move the conditional evaluation far away from your other function. It's a bit cheesy, but you can always do something like:
do {
if (!cond1)
break;
if (!cond2)
break;
if (!cond3)
break;
...
DoSomething();
} while (false);
the while (false) is kind of cheesy. I wish languages had a scoping operator called "once" or something that you could break out of easily.
If I was doing it in Perl, This is how I might run the checks.
{
last unless $var1;
last unless $var2;
last unless $var3;
last unless $var4;
last unless $var5;
last unless $var6;
... # Place Code Here
}
If you plan on using this over a subroutine replace every instance of last with return;
I like to break each condition into descriptive variables.
bool isVar1Valid, isVar2Valid, isVar3Valid, isVar4Valid;
isVar1Valid = ( var1 == 1 )
isVar2Valid = ( var2.Count >= 2 )
isVar3Valid = ( var3 != null )
isVar4Valid = ( var4 != null && var4.IsEmpty() == false )
if ( isVar1Valid && isVar2Valid && isVar3Valid && isVar4Valid ) {
//do code
}
if ( (condition_A)
&& (condition_B)
&& (condition_C)
&& (condition_D)
&& (condition_E)
&& (condition_F)
)
{
...
}
as opposed to
if (condition_A) {
if (condition_B) {
if (condition_C) {
if (condition_D) {
if (condition_E) {
if (condition_F) {
...
}
}
}
}
}
}
and
if ( ( (condition_A)
&& (condition_B)
)
|| ( (condition_C)
&& (condition_D)
)
|| ( (condition_E)
&& (condition_F)
)
)
{
do_this_same_thing();
}
as opposed to
if (condition_A && condition_B) {
do_this_same_thing();
}
if (condition_C && (condition_D) {
do_this_same_thing();
}
if (condition_E && condition_F) {
do_this_same_thing();
}
Most of the static analysis tools for examining code will complain if multiple conditional expressions do not use explicit parenthesis dictating expression analysis, instead of relying on operator precedence rules and fewer parenthesis.
Vertical alignment at the same indent level of open/close braces {}, open close parenthesis (), conditional expressions with parenthesis and operators on the left is an very useful practice, which greatly ENHANCES readability and clarity of the code as opposed to jamming everything that can possibly be jammed onto a single line, sans vertical alignment, spaces or parenthesis
Operator precedence rules are tricky, e.g. && has higher precedence than ||, but | has precedence than &&
So, ...
if (expr_A & expr_B || expr_C | expr_D & expr_E || expr_E && expr_F & expr_G || expr_H {
}
is a really easy multiple conditional expression for mere humans to read and evaluate improperly.
if ( ( (expr_A)
& (expr_B)
)
|| ( (expr_C)
| ( (expr_D)
& (expr_E)
)
)
|| ( (expr_E)
&& ( (expr_F)
& (expr_G)
)
)
|| (expr_H)
)
{
}
There is nothing wrong with horizontal space (linefeeds), vertical alignment, or explicit parenthesis guiding expression evaluation, all of which ENHANCES readability and clarity
If you do this:
if (var1 == true) {
if (var2 == true) {
if (var3 == true) {
...
}
}
}
Then you can also respond to cases where something isn't true. For example, if you're validating input, you could give the user a tip for how to properly format it, or whatever.