Javascript equals === not working as expected - javascript

I am using Ionic2 and Typescript to develop an app.
I have the following code:
public showTick(message: Message): boolean {
console.log('showTick: '+message+' '+message.readByReceiver+' '+this.senderId+' '+message.senderId);
if (message && message.readByReceiver === true && this.senderId && this.senderId === message.senderId) {
console.log('showTick(' + message.content + '): return true');
return true;
}
return false;
}
It outputs the following:
showTick: [object Object] true P8 P8
I would have expected it to get inside the if statement and also print:
showTick(xxx): return true
Is there something wrong with my use of ===?
Any advise appreciated.
p.s. This is the Message model:
interface Message {
_id?: string;
chatId?: string;
senderId?: string;
ownership?: string;
content?: string;
createdAt?: Date;
changeDate?: boolean;
readByReceiver?: boolean;
}
UPDATE
I change the code to:
public showTick(message: Message): boolean {
console.log('showTick: ', message, message.readByReceiver, this.senderId, message.senderId);
if (message) {
console.log('showTick1 ');
if (message.readByReceiver === true || message.readByReceiver === 'true') {
console.log('showTick2 ');
if (this.senderId) {
console.log('showTick3 ');
if (this.senderId === message.senderId) {
console.log('showTick(' + message.content + '): return true');
return true;
}
}
}
}
return false;
}
And get the following ts error (message.readByReceiver === 'true'):
ERROR in ./app/pages/messages/messages.ts
(275,46): error TS2365: Operator '===' cannot be applied to types 'boolean' and 'string'.
UPDATE
The problem seems to be that a boolean type object is holding a string, so the following fixes it.
if (message.readByReceiver === true || message.readByReceiver+'' === 'true')
Two issues:
This fix seems like a hack to me.
I am not sure why the boolean is holding a string. This is an
object coming from a Meteor database defined as boolean.

I think you need to start off with some debugging techniques to provide or gather some more information. One in specific, is going to be the advice put forth by #andrecanilho and #deceze in the question comments.
You need to break down your if statement in to multiple outputs to figure out where your logic is breaking down:
console.log(message.readByReceiver === true)
console.log(this.senderId === message.senderId)
After diagnosing the output of those two statements, our (andre, deceze, and I's) guess is that one of them will be false ... leading you to a solution that you can either resolve yourself, or possibly provide more feedback to the Stack Overflow Community.
UPDATE
You can not compare a type boolean (true) to a type of string ('true') in Typescript.
Change this line:
if (message.readByReceiver === true || message.readByReceiver === 'true')
to:
if (message.readByReceiver === true)
This function should help you diagnose where your logic is breaking down:
public showTick(message: Message): boolean {
console.log(message.readByReceiver === true);
console.log(this.senderId === message.senderId)
if (message && message.readByReceiver === true && this.senderId && this.senderId === message.senderId) {
console.log('showTick(' + message.content + '): return true');
return true;
}
return false;
}

Related

Basic comparison statement in javascript

So I'm trying to run a comparison statement with the firebase SDK.
I've got a function which checks if the phone number or email has a valid invite value / document exists within the database.
I want to add a comparison that says if the invitationData is valid and the claimedDate value is not equal to the data type null or the invitationData is valid and the string value is not equal to null then alert invitation not confirmed. The problem I'm having is with the || or operator I can only seem to get this comparison to work if I'm just doing one argument when I add the or it stops working.
async function checkInvitation(email = '', phone = '') {
try {
let snapshot = firebase.firestore().collection(COLLECTIONS.INVITATIONS);
if (email) {
snapshot = snapshot.where('email', '==', email);
} else if (phone) {
snapshot = snapshot.where('phone', '==', phone);
}
let invitationData = await snapshot.get();
if (!invitationData || invitationData.docs.length === 0) {
Alert.alert(
'Invitation not confirmed',
'Please try again or join our waiting list.',
);
return false;
}
if ((invitationData && invitationData.docs[0].data().claimedDate !== null) || (invitationData && invitationData.docs[0].data().claimedDate != "somestring")) {
Alert.alert(
'Invitation not confirmed',
'This invitation has already been used',
);
return false;
}
return invitationData.docs[0].id;
} catch (error) {
console.log(error);
throw new Error(error);
}
}
If you shorten it (excuse the pseudo nature) it looks as follows :
if (claimedDate !== null || claimedDate != "somestring")
I'm pretty sure that's not what you are meaning. Perhaps you are intending an AND?

checking for null in javascript

if (valid === null) {
return '';
} else if (!valid) {
return 'is-not-valid';
} else if (valid) {
return 'is-valid';
} else {
return '';
}
I have the above if-else-if chain in the code, trying to see if I can write the same logic in one or two lines.
Since you want to distinguish between three types of values, you have to make at least two checks already. The else case will never be hit since either !valid or valid will be true. That also means you can reduce the last else if to an else:
if (valid === null) {
return '';
} else if (!valid) {
return 'is-not-valid';
} else {
return 'is-valid';
}
But you could condense this logic using the conditional operator:
return valid === null ? '' : (valid ? 'is-valid' : 'is-not-valid');
Although I think your example (sans the redundant else block) looks pretty good, you can write it on one line like this:
return valid === null ? '' : (valid ? 'is-valid' : 'is-not-valid')
I prefer the original though

How to check if eval returns nothing in JS

If I want to check if an eval function returns nothing, how do I do it?
I tried to do something like:
if (eval("iwuoinuvwoienvuwope") == "") {
// Do something
alert("Oh NO!");
}
But when I do like that nothing happends.
Here is my full code:
function calc() {
var cal = prompt("Your math....", "1 + 1");
if (cal == null) {
alert("If you don't have a math problem you can gtfo!");
} else if (cal == false) {
alert("If you don't have a math problem you can gtfo!");
}
/* Here I Check if eval is empty */
/* Here it doesn't work */
else if (eval(cal) == "") {
alert("Could you be more specific");
}
/* */
else {
alert("The answer is " + eval(cal));
}
}
<button onclick="calc();">Calculator</button>
eval(code) returns "the completion value of evaluating the given code. If the completion value is empty, undefined is returned." MDN
In your case, a valid math expression returns a Number. Thus you would have to check for typeof result == "Number". If you want to exclude NaN, Infinity and the like, perform additional checks e.g. by isFinite(result).
If you are trying to build a calculator, you should either be expecting a response, an exception or null.
try {
if (r === undefined) {
} else {
// handle response
}
} catch (error) {
// invalid
}
Validating whether it's a Number, and if the mathematical formula is valid will help you identity possible error outputs.

Why does my function not return the error string?

I have function below. It does what it needs to except that it does not return the error string I want.
It always returns "".
I've put breakpoints and seen it step into each error case, but it doesn't return there. It returns at the end of the function.
I'm lost, I'm sure I'm making a really stupid mistake but I don't get it...
Save me the few hairs I have please :)
public validatePanel = () => {
this.Queries().forEach(function(q, i) {
if(q.from() == "" || q.from() == null || q.from() == undefined) {
return "Please select a database";
}
if(q.select().length > 0) {
q.select().forEach(function(s, j) {
if(s.selectoption() == "" || s.selectoption() == null || s.selectoption() == undefined){
return "Please select a stat to show";
}
});
}
if(q.where().length > 0) {
q.where().forEach(function(w, j) {
if(w.whereoption() == "" || w.whereoption() == null || w.whereoption() == undefined){
return "Please select a filter to filter on";
}
if(w.wherevalue() == "" || w.wherevalue() == null || w.wherevalue() == undefined) {
return "Please select a value for your filter";
}
});
}
});
return "";
}
As pointed out by Alex Bykov, your forEach function is not causing a return.
Your question on why not, per the MDN
The return value of the function is undefined
Return
value undefined.
Which means nothing you can do will generate a return value you can use. Also per the MDN there is no way to stop or break the loop other than throwing an exception.
There is no way to stop or break a forEach() loop other than by
throwing an exception. If you need such behavior, the forEach() method
is the wrong tool, use a plain loop instead. If you are testing the
array elements for a predicate and need a Boolean return value, you
can use every() or some() instead. If available, the new methods
find() or findIndex() can be used for early termination upon true
predicates as well.
Which means you will need to throw your exception in the forEach loop and then catch the exception and return the string like below
(unless you use a normal for loop then you can do whatever you please)
try {
this.Queries().forEach(function(q, i) {
if(q.from() == "" || q.from() == null || q.from() == undefined) {
throw "Please select a database";
}
if(q.select().length > 0) {
q.select().forEach(function(s, j) {
if(s.selectoption() == "" || s.selectoption() == null || s.selectoption() == undefined){
throw "Please select a stat to show";
}
});
}
if(q.where().length > 0) {
q.where().forEach(function(w, j) {
if(w.whereoption() == "" || w.whereoption() == null || w.whereoption() == undefined){
throw "Please select a filter to filter on";
}
if(w.wherevalue() == "" || w.wherevalue() == null || w.wherevalue() == undefined) {
throw "Please select a value for your filter";
}
});
}
});
}
catch(err) {
console.log(error);
}

true == false evaluates to true somehow?

I've been working to scrape some webpage that is using the OWASP CRSFGuard project for protection. The library seems to be causing one of my requests to get a 401 so I started digging through their code and noticed the following;
function isValidDomain(current, target) {
var result = false;
/** check exact or subdomain match **/
if(current == target || current == 'localhost') {
result = true;
} else if(true == false) {
if(target.charAt(0) == '.') {
result = current.endsWith(target);
} else {
result = current.endsWith('.' + target);
}
}
return result;
}
From what I can tell, there must be instances where this code is executed; result = current.endsWith('.' + target);. Given true == false is inherently false, how would the code reach that statement? Is this some JS oddity (I know we're not using the strict === equality, but seriously...)?
Answer: It will never reach that code block.
function isValidDomain(current, target) {
var result = false;
/** check exact or subdomain match **/
if (current == target || current == 'localhost') {
result = true;
} else if (true == false) {
if (target.charAt(0) == '.') {
result = current.endsWith(target);
} else {
result = current.endsWith('.' + target);
}
}
return result;
}
var trueFalse = document.getElementById('trueFalse');
trueFalse.innerHTML = isValidDomain('true', 'false') ? 'WTF!' : 'All is good in the JS World';
trueFalse.addEventListener('click', function(e) {
trueFalse.innerHTML = (true == false) ? 'WTF!' : 'All is good in the JS World Still';
});
<div id="trueFalse"></div>
I would say that Blazemonger is most likely correct.
That else if probably had some other condition at some point, and for whatever reason, they decided they didn't want that block of code to execute anymore, so they changed the condition to something that is always false.
It's also not entirely uncommon to see programmers use 1 === 0 as an indication for false. Why they would want to do this is anybody's guess.

Categories

Resources