Why does forEach change my Boolean Value? - javascript

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)

Related

equals comparison operator gives bad result after used four times in a row

I have a class Square with a getter method to determine if a square is valid or not. If my square has sides of 1 my code will return true. If my square has 4 sides of 5 it returns false. Can someone explain what is happening?
As you can see I accessed this in the browser and had the following results:
class Square extends Polygon {
get isValid() {
const testArray = Object.values(this);
return (testArray[0] == testArray[1] == testArray[2] == testArray[3]) ? true : false
}
The expression
testArray[0] == testArray[1] == testArray[2] == testArray[3]
carries out == 3 times, left-to-right.
((testArray[0] == testArray[1]) == testArray[2]) == testArray[3]
The first time, when the array items are equal, the first will evaluate to true:
((testArray[0] == testArray[1]) == testArray[2]) == testArray[3]
(true == testArray[2]) == testArray[3]
If the items are numbers, the next comparison will only return true if the item is 1:
console.log(true == 1);
console.log(true == 2);
console.log(true == 5);
This is because, when using abstract equality comparison ==, when a boolean is compared to a number, the boolean is coerced to a number first, and the numeric value for true is 1.
console.log(Number(true));
The third comparison has the same trouble.
To fix it, instead take the first value (or any value), and use .every:
const oneVal = testArray[0];
return testArray.every(val => val === oneVal);

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; });

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

Alert Based on Else/If In

very new to coding. I am testing to see if I can make an alert display based on a variable. I have the below code and I am trying to figure out why, in its current state, it is not displaying the "bye" alert. Here is the code:
document.getElementById("square").onclick=square;
function square(){
var test="a";
if (test="v") {
alert("hi");
}
else{
alert("bye");
}
}
You are using = which is an assignment operator.
Problem is in line
if (test="v") {
instead of =, use
if (test== "v") {
OR
if (test==="v") {
The identity (===) operator behaves identically to the equality (==) operator except no type conversion is done, and the types must be the same to be considered equal.
In your if statement, you need to write:
if (test === "v") {
alert("hi");
}
The way you have it right now, if (test="v") sets the variable test to the value v before evaluating the if statement. This is basically the same as doing this:
function square() {
test = "a";
test = "v";
if (test) {
alert("hi");
} else {
alert("bye");
}
}
Here, if(test) just asks if the variable test is not null, undefined, or an empty string ''. Because your variable does have a value "v", if(test) will always be true, so alert('hi') will always be run.
Because you are using = instead of == to compare variable test with value v.
The equal operator is for assignments: you use it to assign a value to a variable.
An assignment expression return the value you're assigning, so, in your case, v.
And since in javascript every non-empty string is coerced as true boolean value, your if branch is executed.
You should have used the == or === operator instead.
The == operator coerced two values to the same type, and return true if they are equal. So, for example,
2 == 1 + 1 => true
but also
"2" == 1 + 1 => true
The === operator is for strict equality. It doesn't coerce values type, and only return true if they are equal both in type and value. So, for example,
2 == 1 + 1 => true
but
"2" == 1 + 1 => false
because you're comparing a string with a number
To check a condition you should use a == b to check if value a is equal to value b
in your code you set the value of test variable to 'v'

testing multiple variables in a conditional ? Dom 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");
}
}

Categories