Optional parameters in Meteor router - javascript

I have a path in Meteor
path: '/my-url/:groupId?',
I have added the question mark to indicate that sometimes groupId is not used. In data I check whether the group id is set with this.params.hasOwnProperty('groupId') but I have come across that sometimes the router thinks groupId is set even if it isn't (don't know why) but the value is undefined.
Therefore, I tried
console.log(this.params.hasOwnProperty('groupId'));
console.log('groupId' in this.params);
console.log(this.params.groupId);
and they evaluate to
> true
> true
> undefined
So I guess hasOwnProperty is not the best way to check whether groupId is set since it doesn't check for undefined values.
What will be a better way to check this? Why does hasOwnProperty evaluate to true even if my url is /my-url?

I think you've already answered yourself on your question. I have same problem and my check is:
if (this.params.groupId) {
} else {
}
This is not yet confirmed, but I think as long as you provide :groupId, you're already have that in params, regardless it exists or not.

Related

Is there a downside to using [true, 'true'].includes(someVariable) to check if a value is true?

In our system we can not always be sure if a parameter was given as String or as a Boolean value (dynamic typing ahoi!), therefor, if e.g. we want to check if a certain flag was passed as true (so either boolean true or string 'true'), we usually check it using one of these options:
if (condition + '' === 'true')
which I don't like because of the implicit typecast
if ({true: true, 'true': true}[condition])
which I don't like because it's rather complex to read.
if (condition === true || condition === 'true')
which looks somewhat ugly to me and has an old feel to it.
Therefor, since I want to consider all options : is there a downside to using this variant:
[true, 'true'].includes(someVariable)
(Besides it being sort of a yoda-condition)
Edit: For completion, here are even more ways to check what I want to do:
if (condition.toString() === 'true')
if (String(condition) === 'true')
I think I'll stick with regular === 'true' || === true, checks, but it I'd still like to have my original question answered if possible.
if (condition === true || condition === 'true') reads as "Value is true or a string that says 'true'". Which is what you're trying to do. This is just an opinion, but I believe when trying the code readable, it's most important that it reads the way it acts.
[true, 'true'].includes(someVariable) reads as "this array contains our value". It is not hard to understand, but it does not come natural to me at all. It's not a piece code typically used for this and may stumble your colleague reading the code for a split second.
Finally, I think that you should ideally make sure to sanitize the data as soon as possible and allow the deeper processing code to make some reasonable assumptions about their contents instead of crowding it with tests like the one this question is about. Assumptions are good for both the programmers and for the CPU.
CPU
The downside, if any, compared with all the other methods is not worth consideration when the calling rate is low.
However, if the condition is checked at a very high frequency and if every cpu cycle consumed by it makes an impact, I don't think traversing an array to check truthy is the best thing to do.
Readability
Should a simple truthy check deserve special attention and thought when a programmer's eyes are traversing a function is another question. There are reasons why spelling mistkaes in this sentence may not be detected at once. These are the same reasons why some familiar statements in the code shouldn't be read fully to understand what goes on.

How to check if NOT using Javascript bitwise operators?

I have a function that checks whether a user is premium by checking its flags:
isUserPremium() {
return this.flags & Flags.PREMIUM; // returns true
}
Now let's say that I'd want another function, but this time to check whether the user is free, but using the same flag. I tried negating the returned value, but I'd like to know if there was a better way to do this.
isUserFree() {
return !(this.flags & Flags.PREMIUM); // returns false
}
There isn't a way of checking whether a flag is not set with a single operator. I can suggest using !isUserPremium() instead of isUserFree() later in the code - don't create functions that invert a value returned from another function. However, make sure that you don't rely on this for security. Everything that is executing in the browser can be easily manipulated.

.deny Meteor use.. can't get it to work

I'm trying to deny a question to be submitted if it has a length of 0. But I don't quite understand Meteor deny.
Here's what's going on.
I am updating the question. It is currently set at "yes"
I update it to "yessir"
I console log it as follows:
Questions.deny({
update: function(userId, question) {
console.log(question.question.length);
}
});
but the result is 3. It seems to console log the field being updated, not what I am updating it TO.
This is a problem because how can I check the length of an input if this thing won't check it when it's being submitted.
Can someone enlighten me?
Have a look at the docs and you'll see that the 2nd argument to update is doc:
doc is the current version of the document from the database, without the proposed update
The only way to validate the length of question is to look at the 4th argument - modifier. The problem with this approach is that you must check the modifier for every possible way it could be modified. Fundamentally, this is why allow/deny is really hard to implement in all but the most simple cases.
Instead, I'd strongly suggest either using collection2 to enforce your schema or using methods to modify your documents.
Recommended reading:
Meteor method vs. deny/allow rules
Allow & Deny: A Security Primer
Collection.deny Function either returns true or flase.
If you want to deny update on certain criteria here goes your code like this
Questions.deny({
update: function(userId, question, fields, modifier) {
// check for critera
if(fields.question.length < 0)
return true // denys update for question length less than 0
else
return false // deny = false means allow = true
}
});

What does the jQuery function $('#myelement').is('*') do?

What does the following code do:
$('#myelement').is('*')
What does the asterisk signify? Since there is only one element, #myelement, I can't understand the point of using is(), which checks if an element matches a set of elements?
This is some seriously existential JavaScript.
$('#myelement').is('*')
It will fail whenever #myelement doesn't exist, and return true otherwise.
Basically check to see if an element exists or not. Not the best method...
is checks the element fits the criteria. In this case, "*" means all elements.
So, it simply returns true if the previous selector returns anything.
Take a look here for an example: http://jsfiddle.net/b7DwB/
http://api.jquery.com/is/
Pretty much what it does well from my understanding of it at least, and how I tend to use it. Is return true or false on whatever its called on.
Example I have a checkbox that I want to make sure is checked before I submit my form via AJAX I would do something like
if( $('input#tosCheck').is(':checked') ){
/*its checked submit form*/
}else{
alert('Error');
}
All in all the link to the API from jQuery better describes it then I ever could, but I wanted to at least share an example of use to help you gauge some idea.
Can't say I've ever seen that jQuery code used before, but it seems to be a poor way of checking for the existence of an element. Since * is the universal selector, the expression in question will always return true if #myelement exists, otherwise it will return false.
I say this is a "poor" way of checking the existence of an element because you can simply check the length of the jQuery object instead:
$('#myelement').length > 0
I haven't done any testing, but I assume the above is faster since it doesn't have the overhead of the is() function call.

JavaScript string comparison fails randomly

I’m having a pretty weird bug occurring in my JS application on a random basis. Basically, the script fails to accurately compare two strings. More specifically, at times does not see two identical strings as identical: ('blah' == 'blah') returns false.
The funny thing is that on another try, the same two strings may be admitted to be identical (statement returns true). I never managed to figure out the pattern. I’ve also tried to use === instead of ==; this didn’t help.
I couldn’t think of a better way to demonstrate and prove this ridiculous bug other than by recording a screencast. So here it is: http://www.screenr.com/klOs. I keep giving correct answers for each quiz in that video, but closer to the end you will how my answers for ‘Japan’ and ‘Taiwan’ will be regarded as ‘wrong’; the console will also show the given answer string, the correct answer string, and the result of their comparison (false ?!!).
So what could possibly be the reason for this odd behaviour and how do I get around fixing it?
You can see the code with the comparison statement in the screencast. The ‘params.givenAnswer’ comes directly from the button text label:
//*** Options for answering the card quiz
quizOptions = new Ext.Panel({
id: 'quizOptions',
[…………]
listeners: {
el: {
scope: this,
tap: this.checkAnswer
}
}
});
checkAnswer: function(container, element) {
// Get the text value of the button clicked
var answer = Ext.fly(element).dom.innerText;
Ext.dispatch({
controller: 'Practice',
action: 'checkAnswer',
givenAnswer: answer
});
},
UPDATE Thank you #JAAulde and #Mike! I’ve tried to include the quotes and the var type in the logging and I got this result:
Now it’s clear why the string comparison fails: there seem to be an extra line break of sorts in the first string. It’s still very weird, since it didn’t not appear as a blank new line in the previous logging, and most importantly, it appears there randomly (notice how ‘Taiwan’ was accepted this time without any problems).
I’ve included a simple line-break removal rule for the answer strings, and now everything seem to be working fine. Thanks a lot everyone!
Using === is a strict equality comparison. This means that the data type and the contents are being compared. They both (data and type) must be the same to equal and return true.
When you switched your strict comparison to == the test should have worked even though the data types were different. It failed however because of the extra blank spaces.

Categories

Resources