Javascript function formatting - javascript

I'm concerned my if condition is not correctly formatted.
Does this look right to you?
function validateCoupon( form ){
if (form.textCoupon.value.length ){
if (form.textCoupon.value.toLowerCase() == "Item01") {
_gaq.push(['_trackEvent', 'Coupon', 'Activated', 'Item01']);
}
if (form.textCoupon.value.toLowerCase() == "Item02") {
_gaq.push(['_trackEvent', 'Coupon', 'Activated', 'Item02']);
}
$.get( "/include/checkCoupon.php", { coupon: form.textCoupon.value }, validateShipping );
}
else {
form.textCoupon.style.border = '';
validateShipping( "yes" );
}
return false;
}

Well, something appears to be a redundancy: form.textCoupon.value could be Item01 or Item02. If it's one it couldn't be the other, so I'd suggest you a switch statement.
Another problem is if you call .toLowerCase() this never will return Item01 but item01, and string equality is case-sensitive. Either call this function to both parts of condition or just don't use it.

If this were my code, this would be how I wrote it:
var validateCoupon = function (form) {
var textCoupon = form.textCoupon,
value = textCoupon.value,
track = function (value) {
_gaq.push(['_trackEvent', 'Coupon', 'Activated', value]);
};
if (value.length) {
if (value === 'Item01' || value === 'Item02') {
track(value);
}
$.get('/include/checkCoupon.php', { coupon: value }, validateShipping);
} else {
textCoupon.style.border = '';
validateShipping('yes');
}
return false;
};

Formatting of the source code is irrelevant to the JavaScript runtime. It's just a matter of personal taste.

Avoid tabs in indentation: they are not rendered identically on all platforms.

Related

shorten if conditions in js

I want to shorten the conditions of a javascript if but I don't know how I can achieve it
code:
if ((!emailValidation() || (!nameValidation()) || (!surnameValidation()) || (!addressValidation()) || (!cityValidation()) || (!postalCodeValidation()))) {
}
I have the conditions defined in this way:
let surnameValidation = () => {
if (apellidoUsuario.value.length == 0) {
surnameError();
return false;
}
else if (apellidoUsuario.value.length == 1) {
surnameError();
return false;
}
else {
apellidoUsuario.focus;
apellidoUsuario.style.border = '0';
apellidoUsuario.style.backgroundColor = 'transparent';
apellidoUsuario.style.outline = '1px solid #00ffb1'
apellidoUsuario.style.transitionDuration = '0.4s'
return true;
}
I appreciate any help! :)
You can remove all unnecessary parenthesis in your if condition:
if (
!emailValidation() ||
!nameValidation() ||
!surnameValidation() ||
!addressValidation() ||
!cityValidation() ||
!postalCodeValidation()
) {
}
Other than that, there's not really a clean, readable way to shorten your code.
Proposition #1:
I would probably get those validations into a variable or function:
validations() {
return [
emailValidation(),
nameValidation(),
surnameValidation(),
addressValidation(),
cityValidation(),
postalCodeValidation()];
}
and then I would:
if(validations().some(x=> !x)){
...
}
since validations return an array you can just use the some operator to find any invalid value.
Proposition #2:
I particularly would:
valid() {
return [
emailValidation(),
nameValidation(),
surnameValidation(),
addressValidation(),
cityValidation(),
postalCodeValidation()].every(x => x === true);
}
and then I would:
if(!valid()){
...
}
It is always cleaner to use true conditions on if statements instead of false ones.
References: Clean Code - Uncle Bob.

Alternate structure for a sequence of If statements?

I'm programming a poker program in JavaScript. I have a Hand class that has the properties "cards", "value" and "valueCards". The value property is an integer that corresponds to a hand type, and the valueCards is the array of five cards that also corresponds to the hand type. For example, if my original seven cards(contained in the cards property) contains a flush, this.value will flip to 6, and this.valueCards will equal only the five cards that equal the highest flush.
I have one method for each hand type, and ALL of them change the value and valueCards if that hand type is detected. I have an accessor method for value called getValue, so when I went to make a method to run all the tests on a hand and keep the highest one, it came out looking like this:
POKER.Hand.prototype.getTrueValue = function () {
this.testStraightFlush();
if(this.value == POKER.HAND_TYPE.STRAIGHT_FLUSH){ return; }
this.testQuads();
if(this.value == POKER.HAND_TYPE.QUADS){ return; }
this.testFullHouse();
if(this.value == POKER.HAND_TYPE.FULL_HOUSE){ return; }
this.testFlush();
if(this.value == POKER.HAND_TYPE.FLUSH){ return; }
this.testStraight();
if(this.value == POKER.HAND_TYPE.STRAIGHT){ return; }
this.testTrips();
if(this.value == POKER.HAND_TYPE.TRIPS){ return; }
this.testTwoPair();
if(this.value == POKER.HAND_TYPE.TWO_PAIR){ return; }
this.testPair();
if(this.value == POKER.HAND_TYPE.PAIR){ return; }
this.getHighCards();
};
I mean, the method works fine. It just bothers me, like maybe I should be doing it a different way. Does this go against convention?
If you change your this.test* functions to return true if the "hand" is found, or return false if not - then you could do something as ugly, yet somehow satisfying, as
POKER.Hand.prototype.getTrueValue = function () {
this.testStraightFlush() ||
this.testQuads() ||
this.testFullHouse() ||
this.testFlush() ||
this.testStraight() ||
this.testTrips() ||
this.testTwoPair() ||
this.testPair() ||
this.getHighCards();
};
or
change your this.test* functions to check only if this.found is false, and set this.found = true if a hand is found, so you'd simply
POKER.Hand.prototype.getTrueValue = function () {
this.found = false;
this.testStraightFlush();
this.testQuads();
this.testFullHouse();
this.testFlush();
this.testStraight();
this.testTrips();
this.testTwoPair();
this.testPair();
this.getHighCards();
};
Not an answer but I would redesign your functions :
Each method should return the prop itself :
function testFlush ()
{
if (...) return POKER.HAND_TYPE.FLUSH;
return null;
}
function testStraightFlush()
{
if (...) return POKER.HAND_TYPE.StraightFlush;
return null;
}
This way , you'll be able to get both value and check for truness.
POKER.Hand.prototype.getValue= function ()
{
return this.testFlush () || testStraightFlush()
};
Just for the fun of it, you could redesign the tests like this:
POKER.Hand.prototype.getTrueValue = function () {
var tests = [
[ "testStraightFlush", POKER.HAND_TYPE.STRAIGHT_FLUSH ],
[ "testQuads" , POKER.HAND_TYPE.QUADS ],
[ "testFullHouse" , POKER.HAND_TYPE.FULL_HOUSE ],
... etc...
];
for (var test in tests) {
var fun = this[tests[test][0]];
var val = tests[test][1];
fun();
if (this.value == val) {
return;
}
}
this.getHighCards();
};
Or the functions might simply return a boolean, so you could have a simpler tests array
var tests = [
"testStraightFlush",
"testQuads" ,
"testFullHouse" ,
... etc...
];

Call function only once after a map()

I am having an issue on Nodejs, I need to call a function only once when item.IS_RACING === 1
look
_.map(recordsets, function(items) {
return _.map(items, function(item) {
if (item.IS_RACING === 1) {
_this.getRacing();
}
});
});
I have that _this.getRacing(); which is being called everytime the conditional is true, but if there is 20 items with IS_RACING === 1, so the function _this.getRacing(); is going to be call 20 times. I need something like, once the app detects when the first IS_RACING === 1 comes up, then fires _this.getRacing(); only once.
Any recommendation ?
As Pointy pointed out (sorry) in the comments, you really don't want to use map() to do this.
Think of the problem in terms of how you would explain it to another developer.
If any of the record sets has an item that is racing, I want to call getRacing().
Now, write code that represents your intent.
var somethingIsRacing = _.some(recordsets, function(items) {
return _.some(items, function(item) {
return item.IS_RACING === 1;
});
});
if(somethingIsRacing) {
_this.getRacing();
}
This code follows a principle called Command-Query Separation, where you first query to find the information you need using a functional style of programming, then you perform actions that will have side-effects using an imperative programming style.
A flag variable usually does the trick:
var getRacingCalled = false;
_.map(recordsets, function(items) {
return _.map(items, function(item) {
if (item.IS_RACING === 1 && !getRacingCalled) {
_this.getRacing();
getRacingCalled = true;
}
});
});
Try to do it with a closure:
var closure = (function() {
var fired = false;
return function (item) {
if (!fired && item.IS_RACING === 1) {
fired = true;
_this.getRacing();
}
};
})();
_.map(recordsets, function(items) {
return _.map(items, closure(item));
});

Javascript variable comparison

I have javascript with global variable declared:
var IsUserAllowed = false;
And I have a function:
function setSelectedIdsInput(inputLogicalId) {
if (IsUserAllowed) {
This does not work, I assume the value of IsUserAllowed is in string.
So i did:
var isUserAllowedStr = IsUserAllowed.toString().toLowerCase();
if (isUserAllowedStr == "true") {
This works, Since im new to java script i wanted to know if its ok to compare strings like this.
This due to fact that doing:
if (isUserAllowedStr.localeCompare("true")) {
Did not work either !
Thanks!
Update - i suspect the global var was string and not Boolean. this why the if failed. when i did alert(IsUserAllowed) the output was "False"
var IsUserAllowed = false;
then
function setSelectedIdsInput(inputLogicalId) {
if (IsUserAllowed) {
// something true
} else {
// something false
}
or
if(IsUserAllowed === true)
but it is useless.
Try:
if (isUserAllowed === true) {
}
isUserAllowed is a boolean (true / false):
You can check it by simply doing
if (isUserAllowed) { }
Or
if (isUserAllowed === true) { }
Your example should work as expected.
You can play around in this JSFiddle to test for yourself: http://jsfiddle.net/bT8hV/
var IsUserAllowed = false;
function setSelectedIdsInput() {
if (IsUserAllowed) {
alert('TRUE');
}
else {
alert('FALSE');
}
};
setSelectedIdsInput();

Return from inner function in JavaScript?

I have a jQuery-powered JavaScript function which iterates over a list of fields and checks to see whether they are empty; if so, blocks the submission of the form.
required_fields.forEach(function(field) {
if (field.val() == '')
{
field.addClass('field-highlight');
return false;
}
else
{
field.removeClass('field-highlight');
}
});
// I want to return to here from the return false point
How can I structure this differently to do what I want?
Just use a variable to keep track of the validation:
var is_valid = true;
required_fields.forEach(function(field) {
if (field.val() == '') {
field.addClass('field-highlight');
is_valid = false;
return false;
} else {
field.removeClass('field-highlight');
}
});
return is_valid;
Or, you can just use the field-highlight class as well:
required_fields.forEach(function(field) {
if (field.val() == '') {
field.addClass('field-highlight');
return false;
} else {
field.removeClass('field-highlight');
}
});
return $('.field-highlight').length == 0;
use a boolean in the forEach closure, which would be set to true, if the field value is empty. Check that value before submission of form
It sounds like you want to do the following
Update the elements with the field-highlight class based on whether or not they have a value
Block the form submission if any are empty
If so then try the following
var anyEmpty = false;
required_fields.forEach(function() {
if ($(this).value() == '') {
$(this).addClass('field-highlight');
anyEmpty = true;
} else {
$(this).removeClass('field-highlight');
}
});
if (anyEmpty) {
// Block the form
}
Did you write the "forEach" function? If so, that could check the return value of the anon function, and if it is ever false, stop iterating.
If your required_fields is a jQuery object, you could just do this:
var stop = required_fields.removeClass('field-highlight')
.filter("[value == '']").addClass('field-highlight')
.length;
return !!stop
Or perhaps more efficient like this?
var stop = required_fields.filter('.field-highlight').removeClass('field-highlight')
.end().filter("[value == '']").addClass('field-highlight')
.length;
return !!stop

Categories

Resources