Background: Below coding work fine, and i am able to use both function and return the expected value.
Question: Is there any way to simplify below function coding?
red_messages_disabled_p1() {
let s = this.status;
if (s.red_messages[0] === null) {
return 'none';
} else {
return 'inline-block';
}
},
red_messages_disabled_p2() {
let s = this.status;
if (s.red_messages[1] === null) {
return 'none';
} else {
return 'inline-block';
}
},
What did I try?
I tried to figure it out but no idea, guessing it's not possbile to simplify any more, am i correct?
Expecting?
I expecting there maybe simplify way for this coding.
First option :
red_messages_disabled_p(i) {
return this.status.red_messages[i-1] === null ? 'none' : 'inline-block';
}
Second option :
red_messages_disabled_p(i) {
return this.status.red_messages[i-1] ? 'inline-block' : 'none';
}
Get rid of code duplication. Both of your functions contain the same logic. So move that logic into a separate method as shown below:
class MyClass {
status = {red_messages: []}
redMsgDisplayStyle(msg) {
if (msg === null) {
return 'none';
}
return 'inline-block';
}
red_messages_disabled_p1() {
return this.redMsgDisplayStyle(this.status.red_messages[0])
}
red_messages_disabled_p2() {
return this.redMsgDisplayStyle(this.status.red_messages[1])
}
}
This will not only simplify the code, but also make it less error prone in case of you decide to change the logic in the future.
Also, replacing if-else with a ternary operator is probably not a good idea because: 1) it doesn't actually simplify the logic, just a different syntax and 2) ternary operator is less readable.
use a parameterized function
red_messages_disabled(index) {
let s = this.status;
if (s.red_messages[index] === null) {
return 'none';
} else {
return 'inline-block';
}
}
red_messages_disabled_p1() {
return this.red_messages_disabled(0);
};
red_messages_disabled_p2() {
return this.red_messages_disabled(1);
};
Use a ternary operator
red_messages_disabled_p1() {
let s = this.status;
return s.red_messages[0] === null ? 'none' : 'inline-block';
}
red_messages_disabled_p2() {
let s = this.status;
return s.red_messages[1] === null ? 'none' : 'inline-block';
}
There are already lots of good answers for this question, but I wanted to submit my own solution.
const redMessageDisabled => (index) {
return (s.red_messages[index] === null)?"none":"inline-block";
}
However, I think you can just pass s.red_messages[index] to the function
const redMessageDisabled => (data) {
return (data === null) ? "none" : "inline-block";
}
Related
I am trying to jQuery-like script that supports selectors, show, hide, text, and html methods.
Running a test, no matter which method I call, it always throws a custom "No Element Selected" error. How do I fix this?
The full code is here --> https://jsfiddle.net/7ado13vg/
The relevant code is below
var storingAttributes = {};
class MONEY {
constructer(string) {
try {
//check for action
if (string != null) {
//Check Selection Type
storingAttributes.selectorArray = string.split('')
if (storingAttributes.selectorArray[0] == '#') {
storingAttributes.selectionType = 'id';
storingAttributes.selectorArray.splice(0, 1);
}
if (storingAttributes.selectorArray[0] == '.') {
storingAttributes.selectionType = 'class';
storingAttributes.selectorArray.splice(0, 1);
}
if (storingAttributes.selectorArray[0] != '#' && storingAttributes.selectorArray[0] != '.') {
storingAttributes.selectionType = 'tag';
}
//Select Elem
if (storingAttributes.selectionType == 'id') {
storingAttributes.selectedElem = document.querySelector(string);
}
if (storingAttributes.selectionType == 'class') {
storingAttributes.selectedElem = document.querySelectorAll(string);
}
if (storingAttributes.selectionType == 'tag') {
storingAttributes.selectedElem = document.querySelectorAll(string);
}
}
} catch (error) {
}
}
//The reason I checked what was being selected is because querySelectorAll returns an array, and I do not believe that ids are supported
//trying to use my method 'show'
show() {
try {
if (typeof storingAttributes.selectedElem == 'undefined' || storingAttributes.selectedElem == null) {
throw "No Element Selected";
} else {
if (storingAttributes.selectionType == 'tag') {
for (n = 0; n < storingAttributes.selectedElem.length; ++n) {
storingAttributes.selectedElem[n].style.display = 'block';
}
return;
}
if (storingAttributes.selectionType == 'class') {
for (n = 0; n < storingAttributes.selectedElem.length; ++n) {
storingAttributes.selectedElem[n].style.display = 'block';
}
return;
}
if (storingAttributes.selectionType == 'id') {
storingAttributes.selectedElem.style.display = 'block';
return;
}
}
} catch (e) {
console.log(e);
}
}
}
As you can see, the constructor simply assigns/initializes a value for selectionType, selectedElem, and selectorArray in the object storingAttributes
When you log storingAttributes, it returns an empty object.
The following replaces the code you've posted to show how much simpler it can be written and without erroneously using try/catch.
I understand that it doesn't answer your question, but the code you are working with is really so unnecessarily excessive, it's hard to sift through it to find your problem without refactoring it. Simpler code is easier to debug.
var storingAttributes = {};
// Just test for the non-existance of a value
if (!storingAttributes.selectedElem) {
throw "No Element Selected";
} else {
// switch is more concise when you have a single value to
// check against multiple possible values
switch (storingAttributes.selectionType){
case "tag":
// And since you want to do the exact same code if
// it's "tag" or "class", we'll allow fall through here
case "class":
// The Array.prototype.forEach method makes looping much simpler
storingAttributes.selectedElem.forEach(function(item){
item.classList.add("block");
});
break;
case "id":
storingAttributes.selectedElem.classList.add("block");
}
}
/* Avoid inline styles which lead to duplication of code.
Instead, use CSS classes where possible. */
.block { display:block; }
So I'm trying to check for an undefined object out of multiple ones and then do something with that specific one. This code below works but I can imagine that there's a better way than just using else if 20 times in a row.
if (duelswins === undefined) {
document.getElementById('duels_wins').style.display = 'none'
} else if (duelslosses === undefined) {
document.getElementById('duels_losses').style.display = 'none'
} else if (duelskills === undefined) {
document.getElementById('duels_kills').style.display = 'none'
} else if (duelsdeaths === undefined) {
document.getElementById('duels_deaths').style.display = 'none'
} else if (duelsgoals === undefined) {
document.getElementById('duels_goals').style.display = 'none'
} else if (duelskdr === undefined) {
document.getElementById('duels_kdr').style.display = 'none'
} else if (duelswlr === undefined) {
document.getElementById('duels_wlr').style.display = 'none'
} else if (duelsgwr === undefined) {
document.getElementById('duels_gwr').style.display = 'none'
}
There can be multiple ones of those being undefined but it could also be also none of them.
This is just an example, I'm mostly interested if there's and alternative for using so many if statements just for checking basically the same thing over and over again.
Instead of using individual variables you can put these values into an object and then loop over the keys/values. I'm not sure what your requirements are exactly but this might be a step in the right direction:
const data = {
duels_wins: undefined,
duels_losses: 123,
duels_deaths: undefined,
// ...
};
Object.entries(data).forEach(([key, value]) => {
if (value === undefined) {
document.getElementById(key).style.display = 'none';
}
});
<div id="duels_wins">duels_wins</div>
<div id="duels_losses">duels_losses</div>
<div id="duels_deaths">duels_deaths</div>
I have this lines of code
let value = productDetails.recentPurchaseDate;
if (!productDetails.salesPrice && !productDetails.recentPurchaseDate) {
value = false;
}
if (!productDetails.presentEstimatedValue) {
value = true;
}
Is it possible to refactor, I need to make it function and this two IF? Thanks in advance
You can do it like this
function getValue({
salesPrice,
recentPurchaseDate,
presentEstimatedValue
}) {
if (!salesPrice && !recentPurchaseDate) return false;
if (!presentEstimatedValue) return true
return recentPurchaseDate
}
and then
let value = getValue(productDetails);
Something like that?
const value = yourNewFn();
function yourNewFn() {
if (!productDetails.salesPrice && !productDetails.recentPurchaseDate) {
value = false;
}
if (!productDetails.presentEstimatedValue) {
value = true;
}
return value;
}
Generally I don't think it is well designed if-conditions, but I don't know your business requirements. Let's try with something like this
let value = productHasRecentPurchaseDate(productDetails); //name should math your business goal
function productHasRecentPurchaseDate(productDetails) {
if (!productDetails.salesPrice && !productDetails.recentPurchaseDate) {
return false;
}
else if (!productDetails.presentEstimatedValue) {
return true;
}
else {
return /*you need all if statement path to return some value, this is last one, please provide what those statements should return if both previous conditions fail*/;
}
}
Then use this
if (!productDetails.salesPrice && !productDetails.recentPurchaseDate && !productDetails.presentEstimatedValue ) : value = false ? value = true;
I have a method that takes a language abbreviation and matches it using a .constant dictionary, and returns the matching language name.
How can I do an evaluation with .filter to check whether the passed isoCode/language abbreviation exists?
Here is my method:
angular.module('portalDashboardApp')
.service('ISOtoLanguageService', ['Languages', function(Languages) {
this.returnLanguage = function(isoCode) {
var categoryObject = Languages.filter(function ( categoryObject ) {
return categoryObject.code === isoCode;
})[0];
return categoryObject.name;
};
}]);
Here is the method with some error catching I have tried:
angular.module('portalDashboardApp')
.service('ISOtoLanguageService', ['Languages', function(Languages) {
this.returnLanguage = function(isoCode) {
var categoryObject = Languages.filter(function (categoryObject) {
if (isoCode != null || isoCode != undefined) {
return categoryObject.code === isoCode;
}
else {
return categoryObject.code === 'und';
}
})[0];
if (categoryObject.name != undefined || categoryObject.name != null) {
return categoryObject.name;
}
else {
return "undefined";
}
};
}]);
Thank you!
I would recommend you organize your data at Languagesin an object or map, it'll be much faster and simpler when you fetch your translation by an abbreviation. A short example:
angular.module('portalDashboardApp')
.factory('Languages', function(){
var dictionary = {
ISO: {name: 'International Organization for Standardization'}
};
return {
get: function(abbr){
return dict[abbr];
}
};
}).service('ISOtoLanguageService', ['Languages', function(Languages) {
this.returnLanguage = function(isoCode) {
if(!isoCode) {
return "Answer for empty isoCode";
}
var categoryObject = Languages.get(isoCode);
return (categoryObject || {}).name || "I don't know this abbr";
};
}]);
I'm not sure that this JS works without any syntax error (I've not try to launch it) but idea is that you don't need array and filter on big dictionaries and you are able to get any abbreviation from dict with O(1) complexity even with huge dictionary.
If you don't want to have a refactoring with your code you can do something like this:
angular.module('portalDashboardApp')
.service('ISOtoLanguageService', ['Languages', function(Languages) {
this.returnLanguage = function(isoCode) {
if (!isoCode) {
return;
}
var resultAbbrs = Languages.filter(function (categoryObject) {
return categoryObject.code === isoCode;
});
if (resultAbbrs.length > 0) {
return resultAbbrs[0].name;
}
};
}]);
In this case if isoCode is null, undefined or empty string or this key is not found in dictionary return undefined will be by default. Outside you should check a result of this function with if (result === undefined) ...
I hope it helped you)
What purpose does the question mark serve in the following code snippet:
Template.lists.selected = function () {
return Session.equals('list_id', this._id) ? 'selected' : '';
};
It's known as a ternary operator in a number of languages. It's a shortcut for a full-on if-then statement.
Instead of writing this:
Template.lists.selected = function () {
if(Session.equals('list_id', this._id)) {
return 'selected';
}
else {
return '';
}
};
You do this:
Template.lists.selected = function () {
return Session.equals('list_id', this._id) ? 'selected' : '';
};
The if return is immediately after the question mark; the else return is after the colon.