basic coffeescript find if in array - javascript

In coffee script I'm trying to figure out if something is included in an array or not. But can't seem to figure out the correct syntax. Is there not a way to do this without have to iterate over them?
Thanks,
if $(this).val() is in ["needs_cover","comatose"]
$("#head_count").hide()
else
$("#head_count").show()

Just drop the is:
if $(this).val() in ["needs_cover","comatose"]
$("#head_count").hide()
else
$("#head_count").show()
That would translate to the following JavaScript:
var _ref;
if ((_ref = $(this).val()) === "needs_cover" || _ref === "comatose") {
$("#head_count").hide();
} else {
$("#head_count").show();
}

If this is a common use case, you could write a function, which would also allow you to write a routine that is a bit more compact as well, like so:
hideShowFn = (valSelector, hideShowElSelector, compareArr) ->
if $(valSelector).val() in compareArr then return $(hideShowElSelector).hide()
$(hideShowElSelector).show()
I prefer doing the above as it flattens the code a little bit. This is my preference.
You would call the function like so:
hideShowFn this, '#head_count', ['needs_cover', 'comatose']

Related

Check a variable with multiple values in jquery

I need to check if a variable in if condition as follows.
if(table_block_id == ('customer_details' || 'billing_details' || 'shipping_details')){
}
I know it's the wrong method . Is there any other way to check all values in a single line ?
The easiest way would be to use Array.prototype.includes as EKW suggested in his answer.
However, due to its poor support I would recommend using Array.prototype.indexOf instead:
if(["customer_details", "billing_details", "shipping_details"].indexOf(table_block_id) !== -1){
// code
}
There are a few methods you could use. I quite like the following:
if(["customer_details", "billing_details", "shipping_details"].includes(table_block_id)){
// code
}
You can put the options in array and use jQuery $.inArray() or javascript indexOf() to search array.
var a = 'customer_details';
arr = ['customer_details', 'billing_details', 'shipping_details'];
if($.inArray(a, arr) != -1) // With jQuery
//code
else
//code

Concise way to null check a deeply nested object?

JavaScript for browser
I need to test that one deeply embedded property is not null and if this condition is true, then to change its property. But any its parent can be null also. Therefore I am to check each item in the chain... Therefore I write such ugly code:
if(window[rootNamespace].vm.tech &&
window[rootNamespace].vm.tech.currentWorkType &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection.currentStageSet){
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion
.currentWorkSection.currentStageSet.selectedEntity = item;
}
Is there a shorter method of checking?
(I was the original poster proposing the try-catch method, but based on the discussion on that post you were worried about performance. Here's an alternate approach.)
You can use prototype methods to implement a safe method of accessing subproperties. Here is a method which can safely test for the existence of a nested property:
// Indicates whether an object has the indicated nested subproperty, which may be specified with chained dot notation
// or as separate string arguments.
Object.prototype.hasSubproperty = function() {
if (arguments.length == 0 || typeof(arguments[0]) != 'string') return false;
var properties = arguments[0].indexOf('.') > -1 ? arguments[0].split('.') : arguments;
var current = this;
for(var x = 0; x < properties.length; x++) {
current = current[properties[x]];
if ((typeof current) == 'undefined') return false;
}
return true;
};
A full set of methods can be found here, with sample code.
Timings can be run here, and indicate that using the try-catch method may run a couple of orders of magnitude slower than your original approach when errors are thrown, but is otherwise quite fast. The prototype methods are more generic and can lead to a more declarative style, while offering much better performance than try-catch misses, but obviously not quite as good as hand-crafting if statements each time and/or try-catch without a miss.
I've also blogged about this approach.
Syntax wise I don't think so, but I recommend refactoring at least.
var getCurrentStageSet = function(window){
return window[rootNamespace].vm.tech &&
window[rootNamespace].vm.tech.currentWorkType &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection &&
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection.currentStageSet
}
var setSelectedEntity = function(currentStageSet, item){
currentStageSet.selectedEntity = item;
}
By abstracting this logic your actual set of the property will be more readable, and reusable:
var currentStageSet = getCurrentStageSet(window);
if (currentStageSet){
setSelectedEntity(currentStageSet, item);
}
For such a trivial, self-contained piece of code, it's probably not unreasonable to just catch and ignore the error (possibly log) e.g.
try {
if (window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection.currentStageSet) {
window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion.currentWorkSection.currentStageSet = item;
}
} catch (e) {
// log the error but continue
}
Not sure what else could really go wrong in this type of check, alternatively you could catch a TypeError specifically but not sure it would really matter all that much.
I generally wouldn't recommend catch all's but in this case it seems self contained enough to not be a huge risk.
Anything beyond that requires effort e.g. building an object decorator or a fluent interface type solution, seems overkill to me though.
You can create some variables to get code more readable
var tech = window[rootNamespace].vm.tech;
var workType, curVariant, curVer, curWorkSection;
if(tech){
workType = tech.currentWorkType
}
if(workType){
curVariant = workType.currentVariant;
}
if(curVariant){
curVer =curVariant.currentVersion;
}
if(curVer){
curWorkSection = curVer.currentWorkSection;
}
if(curWorkSection && curWorkSection.currentStageSet){
curWorkSection.currentStageSet.selectedEntity = item;
}
This is the most compact syntax possible in basic JavaScript. It avoids all the null-checking by using error-trapping instead. None of the other answers are as compact because the language is simply missing the feature you're after from C#.
Apparently, I'm being down-voted by the authors of the other, much less compact answers, but this is nevertheless the only single-line answer. Note that other approaches listed here have you creating multiple functions, even. :| If you want compact, this is it.
try { window[rootNamespace].vm.tech.currentWorkType.currentVariant.currentVersion
.currentWorkSection.currentStageSet.selectedEntity = item; } catch (err) {}

JavaScript: shorthand for conditionally adding something to an array

I am writing a Mocha test for a server at work.
I get two potential phone numbers for a customer, at least one of which will be defined.
var homePhone = result.homePhone;
var altPhone = result.altPhone;
I want to use underscore's _.sample function to pick one of these at random. However, one of them may be undefined.
So what I was thinking was something like:
//pseudocode
var phone = _.sample([homephone || (doNothing), altphone || (doNothing)]);
the _.sample function looks like this:
http://underscorejs.org/#sample
the problem of course, is there is no shorthand syntax that I know of to conditionally add something to an array.
The verbose way to do what I want is:
var phoneArray = [];
if(homePhone){
phoneArray.push(homePhone);
}
if(altPhone){
phoneArray.push(homePhone);
}
var phoneSelection = _.sample(phoneArray);
is there a more elegant way to do this in JavaScript?
You could use .filter:
_.sample([homephone, altphone].filter(_.identity))
Another way would be:
_.sample([homephone, altphone]) || homephone || altphone;
Since you're already using underscore, I would suggest leveraging compact:
var phone = _.sample(_.compact([homephone, altphone]));
This is basically a shortened version of dave's answer, since compact is literally implemented as function(array) { return _.filter(array, _.identity); }.
What about:
var phone = (homephone && altphone)? _.sample([homephone, altphone]) : (homephone || altphone);
Array literals in JavaScript:
[ 1, 2, 3 ]
...are a way to statically declare which things go in which positions in an array. In other words, when you write the code, you already know where things will go.
In your scenario, the positions are only known dynamically. In other words, you don't know where they'll go until you run the program on a given set of inputs.
So basically what you're asking for is impossible, barring any radical changes to how array literals work in future versions of JS. However, if all you want is to save typing, #dave's answer is pretty nice. I'm mainly just clarifying that array literals by themselves don't have this capability.

Is it bad practice to place an if/else inside of another else?

if() {
}else {
if (IsAlternateRow=='true')
IsAlternateRow = 'false';
else
IsAlternateRow = 'true';
}
Can I place an if and else statement inside of another else statement?
Note: the question got re-tagged as JavaScript after this answer was posted (it was originally about Java, so this answer is about Java).
In general, it is fine to place an if and an else inside an else clause.
There are, however, several issues with your code. IsAlternateRow=='true' isn't syntactically valid.
If it's a string comparison, you should use double quotes and .equals();
If it's a boolean comparison, you're better off simply doing IsAlternateRow = !IsAlternateRow instead of the entire nested if.
Yes, placing an if inside an else is perfectly acceptable practice but in most cases use of else if is clearer and cleaner. E.g.
if (test) {
// Do something
} else if (otherTest) {
// Do something else
} else {
// Do a third thing
}
infact this is short-hand for
if (test) {
// Do something
} else {
if (otherTest) {
// Do something else
} else {
// Do a third thing
}
}
and the two should compile to almost identical programs in most situations.
Your code example is not very clear and will not compile correctly, clearer sample code may help us to help you out.
try
IsAlternateRow = !IsAlternateRow;
(updated to show what this would look like in your code)
var IsAlternateRow = false;
if(/* -- insert equation here -- */)
{
// do something
}
else
{
IsAlternateRow = !IsAlternateRow;
}
return (IsAlternateRow.equals('true')) ? 'false' : 'true'
In general, I'd say that to answer questions like this, you should ask yourself,
Is this easy to read?
Shallow-nested if/else statements aren't terrible, but once you start nesting ad nauseum, you should probably refactor.
This is fine, but there are easier ways to do what you are doing:
IsAlternateRow = !IsAlternateRow
Yes you can. If you want to evaluate the same object/variable several time you could use a switch statement but in many case staggered if statement will do the job just as well.
To answer your question, yes, you can infinitely nest if/else statements. The code you supplied will compile no problem. Although given that you're talking about Java, I imagine unless that's pseudo code, it isn't going to provide the desired result.
Correct way to do it:
if() {
} else if (IsAlternateRow=='true') {
IsAlternateRow = 'false';
}
else
{
IsAlternateRow = 'true';
}

jquery match() variable interpolation - complex regexes

I've already looked at this, which was helpful to a point.
Here's the problem. I have a list of users propagated into an element via user click; something like this:
<div id="box">
joe-user
page-joe-user
someone-else
page-someone-else
</div>
On click, I want to make sure that the user has not already been clicked into the div. So, I'm doing something like:
if ( ! $('#box').html().match(rcpt) )
{
update_div();
}
else
{
alert(rcpt+' already exists.');
}
However, with existing lack of interpolation that javascript has for regular expressions, is causing my alert to trigger in the use-case where page-joe-user is selected and then the user selects joe-user, which are clearly not exactly the same.
In Perl I would do something like:
if ( $rcpt =~ /^\Qrcpt\E/ )
{
# code
}
All I want to do is change my match() to be:
if ( ! $('#box').html().match(/^rcpt/) )
{
# code
}
if ( ! $('#box').html().match(rcpt) ) seemed a little promising but it, too, fails. Using new RegExp() also does not work using concatenation of complex RE syntax within the function IE $('#box').html().match(new RegExp('^'+rcpt)). I also tried $('#box').html().match('/^'+rcpt'/'). I can only imagine that I'm missing something. I'm pretty new to javascript.
I don't seem to be able to find anything that really addresses such a use-case, here on this site.
TIA
The match function only works on strings, not jQuery objects.
The best way to do this is to put each username into a separate HTML tag.
For example:
<ul id="users">
<li>joe-user</li>
<li>page-joe-user</li>
<li>someone-else</li>
<li>page-someone-else</li>
</ul>
You can then write the following:
if($('#users li').is(function () { return $(this).text() === rcpt; }))
If you want to do it your way, you should call text() to get the string inside the element. ($('#box').text().match(...))
EDIT: The best way to do this using your HTML would be to split the string.
For example:
var userExists = false;
var users = $('#box').text().split(/\r?\n/);
for(var i = 0; i < users.length; i++) { //IE doesn't have indexOf
if (users[i] == rcpt) {
userExists = true;
break;
}
}
if (userExists) {
//Do something
}
This has the added benefit of not being vulnerable to regex-injection.

Categories

Resources