testing multiple variables in a conditional ? Dom Javascript - javascript

The code below represents the idea I am trying to achieve but when I test it doesn't work, what would be the appropriate way to test if q1 and q2 is equal to true?
function processForm() {
if(q1_valid = true && q2_valid = true){
alert("yes");
} else {
alert("no");
}
}

When you use simple = in javascript (and most C-like languages), what happens is that you assign the variable, then return the result of said assignment.
For instance, take the code a = b = true. This can be split up into a = (b = true). Now, if we only look at the part inside the parenthesis, you'll see that what it does is first set b to true, then return b. Then, outside the parenthesis it sets a to whatever b was (which ofcause is true), and returns the value of a. The value of a has nowhere to go, so it's simply dropped.
Now, if we go back to your if-test, what you end up with is basically this:
Set q1_valid to true.
return true (the value of q1_valid) to the && operator.
true is valid for && so it looks at right hand side.
Set q2_valid to true.
return true to the &&.
&& now has true on both sides. Returns true.
Test always passes. q1_valid and q2_valid will always be true after test is run.
The simple solution is to replace = with either == (equals) or === (type and value equals). Your if-check should look like one of the following:
1.
if(q1_valid == true && q2_valid == true)
2.
if(q1_valid === true && q2_valid === true)
Also, since working with booleans (values that are either true or false), the check for equality to true can be omitted altogheter. Another way to do this is simply like this:
if(q1_valid && q2_valid)

Two issues here:
You need to use two equals signs for comparison ==
The variables don't exist in the function, you would need to pass them as parameters when calling the function
function processForm(q1_valid, q2_valid) {
if(q1_valid == true && q2_valid == true){
alert("yes");
} else {
alert("no");
}
}

Related

Why does forEach change my Boolean Value?

I am making a movie database with 3 movies. I want to make a function that takes an argument (array) and console.log("You have watched this movie") when "haveSeen: true"
var movies = [
{
title: ...,
haveSeen: true
},
{
title: ...,
haveSeen: true
},
{
title: ...,
haveSeen: false
}
]
function display(arr) {
arr.forEach(function(element) {
if(element.haveSeen = true) {
console.log("You have watched this movie")
}
})
}
When i run "display(movies)" in the console. The console will change all Boolean values of haveSeen to "true". Why? I want the console to only console.log two times because I have only set two movies to "haveSeen: true"
Your problem is that in your function, you have this line:
if(element.haveSeen = true) {
The single = is the assignment operator, used only when assigning values to variables. Change this to === and it'll work:
if(element.haveSeen === true) {
or because it's Boolean, remove the comparison entirely:
if(element.haveSeen) {
You need to understand the difference between the assignment operator = the equivalence operator == and the equals operator ===.
let x = 1;
if (x = 2) will always be truthy as you just assigned 2 to x and 2 is truthy.
The === operator is what you want to use when testing if something is equal to something else.
if (x === 1) is true and (x === 2) is false.
The == equivalence operator is another thing that you might see people use but many coding standards discourage it's use as the result might not always be what you expect. As in (2 == '2') is true as in the integer 2 is equivalent to the string 2 but they are not equal in the (2 === '2') sense.
Seeing that you are testing a boolean value you don't need any operator and can just use
if (element.haveSeen)

Unnecessary use of Boolean literals in conditional expression

I have a function that checks whether a value is found in array. I want to return a true or false. Current code works but throws and js-standerd/es-lint error "Unnecessary use of boolean literals in conditional expression"
I've searched through a ton of these error messages here but can't seem to wrap my head around it. To me this says 'If the value is found return true otherwise false'
let found = value.find(val => {
return val === item
})
return found ? true : false
I tried this
return value.find(val => {
return val === item
}) || false
Which works but doesn't return a Boolean if found, it returns item.
I know i can make this work in multiple ways but i'm just trying to figure out whether my code is bad or incorrect or whether es-lint is flagging it sort of incorrectly.
The linter is complaining about this:
return found ? true : false
Which should be read as "If found is truthy return true otherwise return false". This structure is referred to as a 'ternary' operator and has been in use since the early days of C, if not before. The ? operator evaluates the condition on the left and returns the first argument if the condition evaluates to true, otherwise it returns the second argument, where the arguments are separated by a colon.
The problem with your code is that returning the condition itself is the equivalent of returning the boolean literals true or false. Therefore, the check and the literals are unnecessary and can be removed. Though, because this is javascript you might want to double negate the condition before returning it, to force it to be a boolean. So, the result looks like this:
return !!found
This is easier to read and there is less chance of it being implemented wrong or misunderstood in the future.
Of course, this could be taken further:
return !!value.find(val => val === item)
In this way, you don't need to even introduce the symbol found into the code at all. Also, this would be better with some(), but I think your question is more about the ternary operator than how to search a list.
My issue was an unnecessary 'else if'.
This produced an error:
// val: "A" | "B" | "C"
const val = "B";
if (val === "A") {
// do something
} else if (val === "B" || val === "C") {
// do something else
}
Removing the 'else' fixed the error:
// val: "A" | "B" | "C"
const val = "B";
if (val === "A") {
// do something
}
if (val === "B" || val === "C") {
// do something else
}
I suppose the reasoning is readability.
return value.some(val => { return val === item; });

Error comparing Array elements in Google script

I have a problem in one of my scripts for a Google Spreadsheet.
In the script I create two arrays, the first one contains a column from the sheet:
var sheet_data = sheet.getRange('C1:C').getValues(); // for example sheet_data = [[""],["text1"],["text2"],[""],["text3"]]
and the second one is hard-coded:
var sheet_names = [["text1"],["text2"],["text3"]];
The sheet_data contains all elements present in sheet_names and I have a while function that finds one specific element (say text1) in sheet_data:
i = 0;
while (sheet_data[i] != sheet_names[1]) { i++; }
In short, I want to find the cell in the column C that contains a specific string. However the loop containing this condition doesn't work for some reason. The loop keeps going on and on but i never increases. I tried the same with a for loop containing an if statement but the if statement containing the above condition fails too. I assumed there must be something wrong with the condition but if I explicitly check the array elements that should be the same, it works:
if (sheet_data[i] == "text1" && sheet_names[1] == "text1") // this works
Why doesn't the direct comparison of the two array elments work?
This looks more to me as a JavaScript issue (I am not familiar with Google Script flavor but the same logic should apply)
You are trying to sheet_data[i] != sheet_names[1], where both sheet_data[i] and sheet_names[1] are ['text1']. In JS, these are 2 different array objects (not same reference), so they would never equal to each other. (different from Python)
The reason that your second solution works is even tricker: when you do ['test1'] == 'test1', because the 2 elements are of different types, JavaScript will try to convert them to the same type, due to your use of == instead of ===. ['test1']'s stringified version is exactly 'test1', resulting in your second solution working.
See example below:
console.log([] == []) // false, different object reference
console.log(['test'] == ['test']) // false
console.log('test' == 'test') // true, both are primitive
console.log(['test'].toString()) // 'test'
console.log(['test'] == 'test') // true, ['test'] converted to 'test' due to ==
console.log(['test'] === 'test') // false, strict comparison without type conversion
// More amazing JS tricks!
console.log([] == 0) // true
console.log([] == '') // true
console.log('' == 0) // true
console.log('' == false) // true
console.log(false == 0) // true
console.log([] == false) // true
// OOOPS...
console.log({} != true) // true
console.log({} != false) // true
// as you see here, NEVER USE == ! use === instead

While Loops Syntax Errors

The course is asking me to form a while loop and I keep getting errors or infinite loops. What am I doing wrong?
var understand = true;
while(understand= true){
console.log("I'm learning while loops!");
understand = false;
}
You are using an assignment operator (=) and not an equals test (==).
Use: while(understand == true)
Or simplified: while(understand)
Update from comments:
=== means the value and the data type must be equal while == will attempt to convert them to the same type before comparison.
For example:
"3" == 3 // True (implicitly)
"3" === 3 // False because a string is not a number.
= means assignment, while == is comparison. So:
while(understand == true)
Also note that while and other branch structures, take conditions. Since this is a Boolean you can just use itself:
while(understand)
Also a note of the difference between == and === (strict comparison). The comparison == will attempt convert the two sides to the same data type before it compares the values. While strict comparison === does not, making it faster in most cases. So for example:
1 == "1" // This is true
1 === "1" // This is false

Javascript or operator not working

var strExt = GetAttributeFromItemTable(itemTable, "Ext", "FileType");
I did a alert for strExt and it resolves.
if (strExt!='wav')
{
// this works
}
if (strExt!='wav' || strExt!='mp3')
{
// this does not work.
}
Your logic is flawed:
if your variable strExt was equal to 'wav' it would not be equal to 'mp3', and versa-visa.
Please explain your desired results more clearly.
I think what you're trying to say is something like (neither 'wav' nor 'mp3'):
if ( !( strExt == 'wav' || strExt == 'mp3' ) )
which is logically equivalent to (not 'wav' and not 'mp3'):
if ( strExt != 'wav' && strExt != 'mp3' ) )
|| says: if any condition is true, It'll return true, without looking at the ones after it.
So true || false is true, false || true is true.
In your case, you say "if strExt is not equal to wav and is not equal to mp3, then execute the code". In case that one of them is true, it executes.
I'm thinking that you're looking for the && symbol. The logical and says "I'll return true only if every condition is true" - when it hits a false, it returns false.
What I think your code should look like:
if (strExt!='wav' && strExt!='mp3')
I would expect the result of the second expression to be True regardless of the value of the string strExt (any extension is either not equal to "wav" or not equal to "mp3"). What do you expect?
Are you certain you don't mean a Boolean AND instead of an OR ("extension is neither 'wav' nor 'mp3'")?
just add the another parenthesis, like so:
if ((strExt!='wav') || (strExt!='mp3'))
{
// this does not work.
}
The logic behind this makes no sense wouldn't you want to do:
if ((strExt !== "wav") && strExt !== "mp3") {
}
AND instead of OR makes more sense in this situation.
If you want to get into second if, when strExt is not equal to both 'wav' and 'mp3' you need to use an && operator.
if (strExt!='wav' || strExt!='mp3')
when strExt='wav' => strExt!='wav' = false; strExt!='mp3' = true => false or true = true and gets into if statement and is the case is similar when strExt='mp3' .

Categories