I am trying to write multiple conditions with ternary expressions in JXS.
But not sure if it's correct.
const applyNowUrl = isSmallerThan.medium ? applyNowMobileURL : isEqualOrLargerThan ? applyNowDesktopURL : applyNowTabletURL
The "applyNowUrl" const should have 3 different URLs based on screen size.
It is correct to have multiple ternary conditions although it makes it difficult to read.
For the sake of clearness, sometimes it's better to create an external function for this:
const applyNowUrl = myFucntion(isSmallerThan, isEqualOrLargerThan);
const myFunction = (isSmallerThan, isEqualOrLargerThan) => {
if (isSmallerThan.medium) return applyNowMobileURL;
if (isEqualOrLargerThan) return applyNowDesktopURL;
return applyNowTabletURL;
}
You can have it like this:
const applyNowUrl =
isSmallerThan.medium ? applyNowMobileURL
: isEqualOrLargerThan ? applyNowDesktopURL
: applyNowTabletURL
You can also use if else recursively
Related
Here is a change to a long code before a render that wasted me time to correct many lines in the code:
Before:
const my_model:MyModel = JSON.parse(localStorage.getItem('my_model')!)
const my_positions:MyModel = JSON.parse(localStorage.getItem('my_positions')!)
After:
const waitformyIcm:Boolean = useDetailMyModelQuery(paramid.id).isSuccess;
const myIcm:undefined | MyModel| any = useDetailMyModelQuery(paramid.id).data
const waitforpositions:Boolean = usePatternPositionsPerModelQuery(paramid.icm).isSuccess;
const positions:undefined | PatternPositions[] = usePatternPositionsPerModelQuery(paramid.icm).data
The consequence is that for almost all the next constants I needed to let the program wait until those first lines completed loading. My question is how to cope with such situations because I feel my approach was not as it should:
For example this previous line would already cause crashes:
const harvestAfter:number[] = [myIcm.length_period1, myIcm.length_period2, myIcm.length_period3]
This was solved by:
const harvestAfter:number[] = waitformyIcm && [myIcm.length_period1, myIcm.length_period2, myIcm.length_period3]
Another challenge was to set a default state with data that had to be loaded first. I solved that with:
const [myFilters, setMyFilters] = useState(myfilters);
useEffect(() => setMyFilters(myfilters), [myfilters && waitforpositions]);
How to properly deal with code that need to wait for previous constants to be loaded in REACT?
Using myconst && ......?
Using useEffect?
Using useRef?
Using async await (how to do that for declaring constants)
Other?
Please don't call the same hook multiple times, that is just a waste of user memory and CPU time. (These hooks are doing work internally and you invoke them twice for no good reason.)
Just don't annotate the types here and assign them to a variable. They are already 100% typesafe from the hook.
Then, use skip:
const icmResult = useDetailMyModelQuery(paramid.id);
const patternsResult = usePatternPositionsPerModelQuery(paramid.icm, { skip: !icmResult.isSuccess });
As for the variable assignment, you could also use destructuring although I don't really see the point:
const { isSuccess: waitformyIcm, data: myIcm } = useDetailMyModelQuery(paramid.id);
As for a default state, there are many approaches. If it is an object you define inline, it would be a new reference on every render, so you best useMemo to get around that:
const filtersWithDefaults = useMemo(() => filters ?? defaultFilters, [filters])
I am trying to filter a List with multiple conditions. The main thing is, I must use the condition if it is true and not if it is false. If the condition is false I should not use that to filter. Below is my code
void performFiltering(bool homeVisits, bool onTheSpotServices)
{
//Check for home and on the spot filtering
if(homeVisits==true)
{
filteredOrganizationList = orgList.where((org) => org.homeVisits==true);
}
else if(onTheSpotServices==true)
{
filteredOrganizationList = orgList.where((org) => org.onTheSpotService==true);
}
else if(homeVisits==true && onTheSpotServices==true)
{
filteredOrganizationList = orgList.where((org) => (org.onTheSpotService==true) ||(org.homeVisits==true) );
}
}
here I have made simple if-else statements. Nothing serious. But I can't do this when there are more conditions. Luckily it is just 2 conditions, but I have much more to come.
Also carefully notice that I have used OR Command in the last statement. That means get results where either homeVisits=true or onTheSpotServices=true
Whats the most effective way of handing this?
there is no need for a cascade of multiple if-elses
instead use a single where with a custom test function:
filteredOrganizationList = orgList.where((org) =>
homeVisits && org.homeVisits ||
onTheSpotServices && org.onTheSpotService ||
... // rest of your filter tests
);
I have onClick that I want to hit a certain function depending on the following logic:
onClick={
approve && this.handleApproveClick,
!approve && !releaseHold && this.handleDeclineClick,
releaseHold && this.handleReleaseHoldClick
}
Oddly enough the last this.handleReleaseHoldClick works, while the others do not. What is the correct way to do this? Or do I really need to create a separate button?
Why does only the last work?
It's a basic comma operator case, where the "comma operator evaluates each of its operands (from left to right) and returns the value of the last operand".
What is the correct way to do this?
Since it's a triple-condition function, I'd suggest you to create a class method and simply secure each of possible cases.
handleSomeClick = () => {
if (approve) {
this.handleApproveClick();
} else if (!approve && !releaseHold) {
this.handleDeclineClick();
} else if (releaseHold) {
this.handleReleaseHoldClick();
}
}
and inside JSX:
onClick={this.handleSomeClick}
have the following function on my collection:
getFiltered: function (status, city) {
return this.filter(function (trainer) {
return ((status === null) ? trainer : trainer.get("TrainerStatusName") === status) &&
((city === null) ? trainer : trainer.get('City') === city);
});
}
What is is best way to deal with nullable params passed in i.e. if city it null then ignore filter/fetch all and if status is null then ignore filter/fetch all
The code above works, but curious about alternatives
Ok, first off, I'm a little confused by your question; the title says its about handling "nullable" parameters, but your code looks like it is dealing with "special case" parameters (specifically "all") ... except for the case of trainer being null, but I don't think that is even possible when iterating through a Backbone collection.
* * Edit * *
OP updated the question, so the above is no longer relevant. I've also updated my answer accordingly.
In any case, there's nothing at all wrong or unusual about your code; ternary operators are a standard way of handling one-off special cases. If you're looking for alternative ideas though, here's one that uses an extra function to DRY out (eliminate the duplication of) your code:
function matchesOrAll(expected, actual) {
return expected === null || expected === actual;
}
getFiltered: function (status, city) {
return this.filter(function (trainer) {
return matchesOrAll(status, trainer.get("TrainerStatusName") &&
matchesOrAll(city, trainer.get("City"));
}
* * Edit * *
Now that we're talking about null and not "all", it's worth pointing out that there is a better pattern for simpler cases of nulls/undefined. If you were just filtering cities, for instance, the code could just be:
getFiltered: function (expectedCity) {
return this.filter(function (currentCity) {
return expectedCity === (currentCity || expectedCity);
}
In other words, you could take advantage of Javascript's "truthiness", and the fact that disjunctive (ie. ||) booleans expressions return the first truthy value. This eliminates the need for a ternary, and many libraries use this pattern to fill in un-provided arguments; for instance, here's a line from jQuery that sets the "target" argument to a new object if none is provided:
target = arguments[1] || {};
Unfortunately though, when you're dealing with properties/attributes of things (eg. trainer.get('foo')) instead of just objects directly (eg. trainer), there's no good shortcut you can use (other than making a function).
I have a decision tree of height 2:
const BOOL isVerticalAnimationRequired = YES;
const BOOL isArgumentEditorExpanded = YES;
const BOOL isSelectionLeftToRight = YES;
UITableViewRowAnimation argumentEditorAnimation;
if (isVerticalAnimationRequired)
{
argumentEditorAnimation = (isArgumentEditorExpanded) ? UITableViewRowAnimationTop : UITableViewRowAnimationBottom;
}
else
{
argumentEditorAnimation = (isSelectionLeftToRight) ? UITableViewRowAnimationLeft : UITableViewRowAnimationRight;
}
My problem is that the code is verbose. Ideally I would like to declare and set argumentEditorAnimation in one statement.
Are there any clever C style tips for handling situation like this?
I think I would not try to fold this into one expression for reasons of clarity, but if you must:
argumentEditorAnimation =
isVerticalAnimationRequired ?
(isArgumentEditorExpanded ?
UITableViewRowAnimationTop
: UITableViewRowAnimationBottom)
: (isSelectionLeftToRight ?
UITableViewRowAnimationLeft
: UITableViewRowAnimationRight);
Alternatively, you can make your code more concise by dropping the {} when they're not needed.
(Consider using shorter identifiers if you want to write these kinds of expressions. The long identifiers make the code verbose as well. E.g., drop the is in your booleans.)
Sometimes logic like this can best be expressed with a small table that you index with your decision criteria.
In this case, I would just use good formatting as larsmans showed in his answer.