The following code is inside a loop which loops through the fields of a form. If isV1User is true, then the field is disabled. If the user has customSetting then don't disable the field. If the user doesn't have it, disable it.
if (field.name === 'themeColor') {
if (this.isV1User) {
field.disabled = false
} else {
field.disabled = this.user.customSetting
? !this.user.customSetting.themePicker
: false
}
}
How to simplify or at least remove the nesting of this code?
Move every if condition to ternary:
if (field.name === 'themeColor') {
field.disabled = !this.isV1User && this.user.customSetting && !this.user.customSetting.themePicker;
}
if (field.name === 'themeColor') {
field.disabled = this.user.customSetting && !this.isV1User ?
!this.user.customSetting.themePicker : false;
}
This isn't really a Stack Overflow question, would fit better on Code Review I guess.
There's only one set of circumstances in which it needs to be true, it seems, so maybe like this?
if (field.name === 'themeColor') {
field.disabled = (
!this.isV1User &&
this.user.customSetting && !this.user.customSetting.themePicker);
}
The first if is still needed because other fields should remain unchanged (I assume).
You can do like this
"themeColor"===field.name && (field.disabled=this.isV1User?!1:
this.user.customSetting?!this.user.customSetting.themePicker:!1);
The way that you have structured your code, it can be minimized to the following equivalent code. Please note that if this.user.customSetting.themePicker is guaranteed to always be true when this.user.customSetting is true, you can set field.disabled = true in a single if statement where the conditional is field.name == 'themeColor':
if (field.name == 'themeColor' && this.user.customSetting) {
field.disabled = !this.user.customSetting.themePicker;
} else if (field.name == 'themeColor') {
field.disabled = false;
}
Or even the following switch statement, depending on how you want your code structured. They both are the same.
switch (field.name) {
case 'themeColor':
if (this.user.customSetting) {
field.disabled = !this.user.customSetting.themePicker;
}
break;
default:
field.disabled = false;
}
Most of these answers break the cardinal rule of ternary statement readability. If your goal is simplistic readability, breaking it down to a simple if/else if statement will do. If you are trying to minimize the code as much as possible, and don't care if it's unmaintainable/hard to read, you should simplify it to a recursive ternary statement. Personally, I find that long ternary statements do not provide significant space-saving, hamper readability, and should be avoided in cases where they are not extremely simple (ie: var x = statement? 1 : 0;)
Try this
if (field.name === 'themeColor') {
field.disabled = this.isV1User ? true : this.user.customSetting ? !this.user.customSetting.themePicker : false;
}
Related
I would like to clean up my code but I can't. I would like to get rid of the nested ternary expressions. I work with react js 17.0.2. Do you have any ideas to help me?
const buildNewFilters = (query, filtersIndex: Array<string>) => {
const newFilters = {};
for (let i = 0; i < filtersIndex.length; i++) {
newFilters[filtersIndex[i]] = router.query[filtersIndex[i]] ? typeof router.query[filtersIndex[i]] == ('string' || 'number') ? [router.query[filtersIndex[i]]] : router.query[filtersIndex[i]] : undefined
if (filtersIndex[i] === 'designers' && newFilters.designers) {
newFilters.designers = newFilters.designers.map(designer => parseInt(designer));
}
}
return newFilters;
};
if (router.query[filtersIndex[i]]) {
if (typeof router.query[filtersIndex[i]] == ("string" || "number")) {
newFilters[filtersIndex[i]] = [router.query[filtersIndex[i]]];
} else {
newFilters[filtersIndex[i]] = router.query[filtersIndex[i]];
}
} else {
newFilters[filtersIndex[i]] = undefined;
}
If you are not used to working with ternary operators, I understand that it's not easy to refactor the code. First, you can read about what ternary expressions are and try them out in the Mozilla Documentation about ternary operators. Basically the part of the code before the ? evaluates to either true or false and if it evaluates to true, the part before the subsequent : is executed (in your case assigned to the variable newFilters[filtersIndex[i]], otherwise the part after the : will be assigned to the variable.
My tip would be to put the line you want to refactor in a text editor to experiment with it, and add line breaks and/or tabs after the ? and : signs to see the structure better and to see what is happening at each step.
I have a program where I have these strings being added to an array. However, there are many strings that are triggered by a certain condition, which can be met multiple times, however I only want it to be added on the first occurrence. So I have implemented a system where the event of adding the string to the array is triggered by the original condition, and a boolean expression. Here is an example of one of those conditions:
if (count >= 10 && displayMulti == true) {
consoleData.shift()
consoleData.push("Multi available")
displayMulti = false
window.localStorage.setItem("display_multi", String(displayMulti))
updateConsole()
}
When the string is added to the array, the boolean, displayMulti, is set to false so that it will not trigger again. However, upon refreshing the page, it will still trigger. I'm not sure why because I feel like I have saving the values to localstorage correctly. Code is below:
if (window.localStorage.getItem("display_multi") != null ) {
displayMulti = Boolean(window.localStorage.getItem("display_multi"))
} else {
console.log("here")
var displayMulti = true
}
There "here" console log statement is not triggered. So I have no idea why this would keep triggering because I don't see how the boolean is true. I've tested at like so many different points I genuinely have no idea what's wrong. I also don't think those values are affected anywhere else in my code. Any help is appreciated.
Here is a solution that properly parses your string as a boolean. Instead of Boolean(), a conditional (window.localStorage.getItem("display_multi") === 'true')(window.localStorage.getItem("display_multi") === 'true') is used.
if (window.localStorage.getItem("display_multi") != null ) {
displayMulti = (window.localStorage.getItem("display_multi") === 'true')
} else {
console.log("here")
var displayMulti = true
}
if (count >= 10 && displayMulti == true) {
consoleData.shift()
consoleData.push("Multi available")
displayMulti = false
window.localStorage.setItem("display_multi", String(displayMulti))
updateConsole()
}
I really need some help with this one, I've been struggling a lot trying to crack the example down on my own for way too long.. the whole issue is that I have an array that includes 15 pictures added by push property & createImage function, the problem though is that I've absolutely no idea how I could use the image in an if-statement like so:
if (check both if the image displayed is the first image within the array and answer equals 'x') return that's a good answer
that's a good answer } else (in case if either the image isn't the first one or answer doesn't equal 'x' return that's not a good answer
So far I've achieved the following, unfortunately enough the program omits the rule regarding the array
var answer = document.getElementById("answer");
var image = newArray[0];
function check() {
if (newArray[0] == true && answer.value == "C") {
window.alert("that's a good answer");
} else if (newArray[0] == true && answer.value == "c") {
window.alert("that's a good answer as well");
} else {
window.alert("that's unfortunately not a good answer");
}
}
Thanks in advance for any form of help
I obviously had to change things a bit since you don't give us the document or newArray, but after adding some dummy data and running it, it works. Can you be more specific about the error(s) you're running into?
Here's my solution:
var answer = "C";
var newArray = [true, false, false, true];
var image = newArray[0];
function check() {
if (image === true && answer == "C") {
window.alert("that's a good answer");
} else if (image === true && answer == "c") {
window.alert("that's a good answer as well");
} else {
window.alert("that's unfortunately not a good answer");
}
}
check();
I'm writing a multiple if statement in Javascript. I've 3 (or more) conditions, and I wanna doSomething() only if all these 3 conditions are true. If only one of these 3 are false, I wanna doSomethingElse(). I think my code it's right, but my problem is on another level.
What if I wanna know for which condition my statement is false?
E.g.: condition1=true, condition2=true, condition3=false.
if (condition1 && condition2 && condition3) {
doSomething();
} else {
doSomethingElse();
};
I've thought that I can put another if statement in the else part.
if (condition1 && condition2 && condition3) {
doSomething();
} else {
if (condition1 == false) {
doWhatIDoWhenC1isFalse();
};
};
Is this the right way? Is there any other way to do this? Maybe faster way!
Thank for your help, and be nice to me, it's my second day on Javascript :)
Since the conditions are mutually exclusive, you can just use an else if without nesting.
if (condition1 && condition2 && condition3) {
doSomething();
} else if (!condition1) {
doWhatIDoWhenC1isFalse();
}
// add more else-if conditions as needed
If only one of your conditions can be false at a time (or if you don't care when two of them are false) then you can just have three else-if clauses and check each condition individually. If you do need to treat the cases where two conditions are false separately, you'll need an else-if for each combination. Pay close attention to the order you list them in if that's the case. The cases where you check if two conditions are both false should come before the cases where you only check one condition.
if (condition1 && condition2 && condition3) {
doSomething();
}else if (!condition1){
doWhatIDoWhenC1isFalse();
}else if (!condition2){
doWhatIDoWhenC2isFalse();
}else{
doWhatIDoWhenC3isFalse();
}
You have to do something along the lines of this. No way to cleanly get which expression that failed.
You may go this way if you want if any one of the condition is false:
if ((!condition1 && condition2 && condition3)||
(condition1 && !condition2 && condition3)||
(condition1 && condition2 && !condition3))
{
doSomethingElse();
} else {
doSomething();
};
It can be:
var x = []; /* an array that will take expressions number that result true */
if(condition1) x.push(1);
if(condition2) x.push(2);
if(condition3) x.push(3);
if( x.length == 2 ){ /* if two conditions got true */
doThingForTwoTrue();
}
if( x.length == 3 ){ /* if three conditions got true */
doThingForThreeTrue();
}
if( x.indexOf(1) !== -1 ){ /* if condition1 got true */
doThingOne();
}
I have an if statement:
if(firstString == "no" && secondString == "no" && thirdString == "no"){
// Do stuff here
}
Is there a prettier way to format this? Using false instead of "no" is not an option, since the data I'm checking is from an AJAX request and I don't control its output. Otherwise I'd write it this way:
if(!firstString && !secondString && !thirdString){
// Do stuff here
}
Thanks
UPDATE:
I know this is totally ridiculous, but it occurred to me that this might actually be the shortest way:
if(firstString + secondString + thirdString == "nonono"){
// Do stuff here
}
Given that the number of strings is known in advance, then you have 2 options as far as I can see..
Leave it as it is. The if statement isn't hard to read, and any alternate formats will either be as complicated or more complicated.
convert the strings to booleans when you retrieve the data from the AJAX request, so that you're storing TRUE or FALSE instead of "yes" and "no". That would allow you to use a your preferred if statement format, and might be more efficient than many string comparisons if you do a lot of them.
In the end, which you do is up to you, but personally I think it would be better to just stick with what you've got. Don't worry about formatting an if statement, it's pretty obvious what it does, and in my opinion doesn't need to change.
If( "no" == firstString && firstString == secondString && secondString == thirdString )
It was a little difficult to determine exactly what you are evaluating to true or false, but this can be tweaked a tad to get what you're looking for.
var checkStrings = function() {
var no = "no",
args = Array.prototype.slice.call(arguments);
for (var i = 0, len = args.length; i < len; i++) {
if (args[i] !== no) {
return false;
}
}
return true;
};
if (checkStrings(firstString, secondString, thirdString)) {
// Do stuff here
}
Sorry, wasn't thinking--this is if you were checking whether ANY were 'no'
if ($.inArray('no', [firstString, secondString, thirdString]) >= 0) {
// Do something if the value is 'no'
}
UPDATED ANSWER
Unfortunately, jQuery doesn't have the reduce() function (another Array extra introduced in JS 1.6, but not available in older browsers) which would do the trick nicely.
Here's one way to check if all are 'no':
var found = true;
$.each([firstString, secondString, thirdString], function (i, str) {
if (str !== 'no') {
found = false;
}
});
It may seem uglier, but it should be shorter if you have a lot more strings to check.
If you want it wrapped in a function you could do:
function allTrue (arr, checkStr) {
var found = true;
$.each(arr, function (i, str) {
if (str !== checkStr) {
found = false;
}
});
return found;
}
if (allTrue([firstString, secondString, thirdString], 'no')) {
// ...
}
function F(var value){
return value === "no";
}
if(F(firstString) && F(secondString) && F(thirdString)){
// Do stuff here
}
Another option, using jQuery.unique:
var uniques = $.unique([firstString, secondString, thirdString]);
if (uniques.length === 1 && uniques[0] === "no") {
// do stuff
}