Conditional statement not working as intended - javascript

I have the following code which is supposed to first check the navigator.platform, and if the user is coming to the page from a device other than an iPhone or iPad, redirect to the given page. However, it is currently redirecting iPad and iPhone devices to that page.
var param = document.location.search.split("?link=");
//IF DEVICE IS NOT IPHONE, REDIRECT USER TO OTHER PLATFORM PAGE
if (navigator.platform != 'iPhone' || navigator.platform != 'iPad')
{
window.location.replace("other-platform.html");
}
else if(param[1] === 'faq-link' && navigator.platform === 'iPhone' || 'iPad' )
{
window.location.replace("#");
}
else if (param[1] === 'footer-link' && navigator.platform === 'iPhone' || 'iPad')
{
window.location.replace("#");
}
else if(param[1] === 'share-page-A-getapp' && navigator.platform === 'iPhone' || 'iPad')
{
window.location.replace("#");
}
else if(param[1] === 'share-page-B-getapp' && navigator.platform === 'iPhone' || 'iPad')
{
window.location.replace("#");
}
else if(param[1] === 'share-page-C-getapp' && navigator.platform === 'iPhone' || 'iPad')
{
window.location.replace("#");
}

Think about the logic here:
if (navigator.platform != 'iPhone' || navigator.platform != 'iPad')
If navigator.platform is equal to "iPhone", then it's not equal to "iPad". If it is equal to "iPad", it's not equal to "iPhone". The if test is therefore always true because all strings are either not equal to "iPhone" or else not equal to "iPad".
The || should be &&.
Subsequently, your tests that involve 'iPhone' || 'iPad' are not doing what you think. Take the first one:
else if (param[1] === 'faq-link' && navigator.platform === 'iPhone' || 'iPad' )
We can add parentheses to show how JavaScript interprets the expression:
else if (((param[1] === 'faq-link') && (navigator.platform === 'iPhone')) || 'iPad' )
That is, it compares param[1] to the string "faq-link" first. If that succeeds, then it compares navigator.platform to the string "iPhone". If that also succeeds, then the test is true. However, if one of those two tests fails, the other side of the || operator is the string constant 'iPad', and that will always be interpreted as true. Thus, each one of those comparison clauses also has an always-true condition.
To fix those, all you need to do is get rid of the tests for "iPhone" and "iPad", because once you fix the very first test as described above, the other tests can safely assume that navigator.platform is either "iPhone" nor "iPad". So that test would be just:
else if (param[1] === 'faq-link')

There is an error on your if conditions, the last one:
For example,
(param[1] === 'faq-link' && navigator.platform === 'iPhone' || 'iPad')
should be
(param[1] === 'faq-link' && navigator.platform === 'iPhone' || navigator.platform === 'iPad').
Also best to group conditions with additional parentheses for clarity, i.e,
( (param[1] === 'faq-link') && (navigator.platform === 'iPhone') || (navigator.platform === 'iPad') )

look at this:
else if(param[1] === 'faq-link' && navigator.platform === 'iPhone' || 'iPad' )
will allways return true because 'iPad' is true.
change like that:
else if(param[1] === 'faq-link' && navigator.platform === 'iPhone' || navigator.platform ==='iPad' )

Related

simplify number validation in if statement JavaScript

I am validating my time in this way
if (
timeInMins != 0 &&
timeInMins != "0" &&
timeInMins != undefined &&
timeInMins != "undefined" &&
timeInMins != null &&
timeInMins != "" &&
!isNaN(timeInMins)
) {
timeInMinsCumulative += parseFloat(timeInMins);
}
Is there any way to make this ugly if-check to sophisticated code?
There are 6 falsy values in javascript: undefined, null, NaN, 0, "" (empty string), and false of course.
So, you can just write
if (timeInMins && timeInMin !== '0') {
timeInMinsCumulative += parseFloat(timeInMins);
}
This uses the coercion behavior of JavaScript and the logical AND operator to simplify your code. The following is very nearly equivalent to your code, but it will also guard against the arguments false and 0n.
if (timeInMins &&
timeInMins !== '0' &&
timeInMins !== 'undefined') {
// whatever
}
Questions for you: do you really expect to ever get the string 'undefined' passed to you? Why do you want to guard against '0' being sent to parseFloat? Are you sure parseInt is not what you want?
It seems you want to check if timeInMins is precise Number type or not.
function isValidNumber(num) {
return typeof num === "number" && !isNaN(num);
}
console.log(isValidNumber(""));
console.log(isValidNumber(undefined));
console.log(isValidNumber(NaN));
console.log(isValidNumber("undefined"));
console.log(isValidNumber(true));
console.log(isValidNumber(false));
console.log(isValidNumber(0));
console.log(isValidNumber("0"));
console.log(isValidNumber(1.234));

Logical Operator || somehow doesn't give desired outcome

I have this variable that toggles if some things are enabled to be edited or not looking like this
enabled: !(parseInt("#Model.Status") === #((int)Status.Active) ||
!(parseInt("#Model.Status") === #((int)Status.Expired)) && '#Model.EditMode' === 'True'),
For some reason if this works for the ones with active status and not expired and if i turn it around and put expired first it works for expired but not active ones.... So i am wrong here somewere the thought is that if the status is either Expired or Active the enabled should be false so that it cannot be edtied all other statuses should be fine.
I have also tried to write it like this with brackets around the second statement
!((parseInt("#Model.Status") === #((int)Status.Expired))
and like this inverting the if but none of it solved it
(parseInt("#Model.Status") !== #((int)Status.Expired)
Great comment by Pointy! but unfortunately it isn't the problem here either because even if I skip the whole && operator I still have the same problem with just
!(parseInt("#Model.Status") === #((int)Status.Active) || !(parseInt("#Model.Status") === #((int)Status.Expired)))
this still gives the same problem
Your condition seems to be wrong. !(parseInt("#Model.Status") === #((int)Status.Active) || !(parseInt("#Model.Status") === #((int)Status.Expired)) && '#Model.EditMode' === 'True')
can be viewed as !(a || !(b) && c) where
a = parseInt("#Model.Status") === #((int)Status.Active)
b = parseInt("#Model.Status") === #((int)Status.Expired)
c = '#Model.EditMode' === 'True'
The AND operator (&&) has higher precedence than ||, so the actual evaluation order can be shown using grouping as !(a || (!(b) && c)) the same way how 2 + 3 * 4 is evaluated as 2 + (3 * 4).
However, the logic presented does not match the requirement. The status should anything but Active or Expired and Edit Mode should be "True". However, it seems that the brackets are mismatched likely due to a typo, since the entire logical expression is negated, and further the second condition is also negated, whereas it shouldn't be.
The correct logical expression is !(a || b) && c. Substituting the logical tests:
!(parseInt("#Model.Status") === #((int)Status.Active) || parseInt("#Model.Status") === #((int)Status.Expired) &&
'#Model.EditMode' === 'True'
I am not familiar with Kendo, but if it's possible to use !== then the expression can be simplified a bit by removing some of the brackets. According to De Morgan's laws !(a || b) is equivalent to !a && !b, so if we perform that substitution, we get !a && !b && c. If we also change from !(parseInt("#Model.Status") === #((int)Status.Active)) to parseInt("#Model.Status") !== #((int)Status.Active) then we end up with:
parseInt("#Model.Status") !== #((int)Status.Active) &&
parseInt("#Model.Status") !== #((int)Status.Expired) &&
'#Model.EditMode' === 'True'

Combination Keydown function not working for Mac Keyboard

I'm trying to show the Searchbar on my application using keyboard shortcuts.
While the keyboard shortcuts work perfectly using a Windows keyboard, the code fails when I'm using a Mac machine with a Mac keyboard.
Following is the function which I've written -
var osName = "Unknown OS";
if (navigator.appVersion.indexOf("Win") != -1) osName = "Windows";
if (navigator.appVersion.indexOf("Mac") != -1) osName = "MacOS";
function showSearchBarOnKeyPress() {
$(document).keydown(function (e) {
if ((e.ctrlKey && e.altKey && e.key === "z") || (osName === "MacOS" && e.keyCode === 90 && e.keyCode === 17 && e.keyCode === 91)) {
searchBarIsShown();
}
});
}
Initially I didn't have the '||' condition in the 'If' statement. The first condition works when using a Windows keyboard. When I checked on a Mac it didn't work. So I had to put in the '||' condition.
For the MacOS condition initially I had used keycodes - 59,55 and 6 as shown in this reference -
https://eastmanreference.com/complete-list-of-applescript-key-codes
On checking in the Mac machine, the keycodes detected were - 90,91 and 17 which I then replaced.
But it still doesn't work.
Can someone please provide their insights/thoughts on this issue?
Thanks
try this:
metaKey is cmd key on mac. altKey is the option key on mac.
var osName = "Unknown OS";
if (navigator.appVersion.indexOf("Win") != -1) osName = "Windows";
if (navigator.appVersion.indexOf("Mac") != -1) osName = "MacOS";
function showSearchBarOnKeyPress() {
$(document).keydown(function (e) {
var modifier = (navigator.appVersion.indexOf("Mac") != -1) ? e.ctrlKey : e.metaKey;
if (modifier && e.altKey && e.key === "z") {
searchBarIsShown();
}
});
}
note that metaKey is not supported on old browseres..
e.ctrlKey and e.altKey are special properties on the KeyboardEvent object that contain the state of these buttons.
e.keyCode === 90 && e.keyCode === 17 && e.keyCode === 91
the property e.keyCode can not be three differrent values at once.
I have little experience with apple but I assume you'd have to manually keep track of the state of these buttons.
a simple statemanager would be:
const keyDown = Object.create(null);
$(document).on("keydown keyup", e => keyDown[e.keyCode] = e.type === "keydown");
so now you can check all three Buttons at once:
keyDown[90] && keyDown[17] && keyDown[91]

checking for empty or whitespaces input text box JavaScript

I'm having web seminars for learning JS and we 're asked to create a simple Form. Now we need to check if an input text-box is empty or it has only white spaces.
Here is the Lab Solution:
if (firstTextBoxContent != "" && firstTextBoxContent != null)
while this is the solution it worked for me:
if (/\S/.test(firstTextBoxContent))
Is my way good enough to stick with it and why Tutor's way didn't work at all?
The lab solution is bad, as it first checks if firstTextBoxContent is empty, and then checks if it is null/undefined.
If it is undefined, the first check will result in a reference error and should therefore be in the reverse order.
However, the lab solution doesn't check for whitespaces.
Your solution won't work if firstTextBoxContent is undefined, so if there's a possibility for that, make sure to check like so:
firstTextBoxContent != null && /\S/.test(firstTextBoxContent)
some tests:
> firstTextBoxContent = undefined
> firstTextBoxContent != null && /\S/.test(firstTextBoxContent)
false
> firstTextBoxContent = null
> firstTextBoxContent != null && /\S/.test(firstTextBoxContent)
false
> firstTextBoxContent = ''
> firstTextBoxContent != null && /\S/.test(firstTextBoxContent)
false
> firstTextBoxContent = ' '
> firstTextBoxContent != null && /\S/.test(firstTextBoxContent)
false
> firstTextBoxContent = ' b'
> firstTextBoxContent != null && /\S/.test(firstTextBoxContent)
true
Another way to do this is
firstTextBoxContent != null && firstTextBoxContent.trim() !== ''
to avoid this wisdom:
You have a problem. You try to solve it with regex. Now you have two problems.

JavaScript comparison issues

I need this comparison in my javascript to work.
if ((q2 != '' && correct2 != 'True') || (q2 != '' && correct2 != 'true') || (q2 != '' && correct2 != 'false') || (q2 != '' && correct2 != 'False'))
{
alert("You must enter true or false.");
}
q2 and correct2 are textboxes and if q2 has something in it and correct2 doesn't equal true, True, false, or False then I want the message box pops up. My code is not working. If I put true or false in the blank the error message still shows up.
EDIT
I have found how to make it work. Instead of putting || between the comparisons I put && and it works perfectly.
To get the value of a text input, do something like
var q2Value = q2.value;
For the conditionals, || is or, not or, and everytime you do a comparison you need 2 values/variables
(correct2 !== 'True ) || (correct2 !== 'true')...
You can see I wrapped the comparisons in parenthesis so its perfectly clear what should be compared to what, even if it isn't strictly necessary.
Since you need q2 to be correct before comparing the other condition, you can use a nifty feature called short-circuiting. Basically, && only proceeds if the first comparison is truthy, so you would do
(qa2 !== '') && (the rest)
Note that if a user doesn't enter the value at all, when you get the value of the text field it will be undefined (I think), not '''. So you should really just do
qa2 && (...)
Basically null, undefined, and '' are all falsy in javascript, so if qa2 is any of those values, the second part of the and won't be processed.
This should work.
if ((q2 != '' && correct2 != 'True') || (q2 != '' && correct2 != 'true') || (q2 != '' && correct2 != 'false') || (q2 != '' && correct2 != 'False'))
{
alert("You must enter true or false.");
}
try this
if(q2 !== '' && !(correct2 == 'true') && !(correct2 == 'True') && !(correct2 == 'False') && !(correct2 == 'false'))
{
alert("You must enter true or false.")
};

Categories