Better way to write ngClass condition - javascript

I am trying to think of a cleaner way to write this condition:
[ngClass]="{
'class1':
image.isAvailable && (image.property !== true && !null),
'class2':
image.isAvailable && (image.property === true && !null)
}"
So image.property sometimes can be NULL, and I am trying to handle it...I know I'm missing something obvious but don't know what. Any help much appreciated

You could use safe navigation operator ?. with ternary operator.
[ngClass]="(image?.isAvailable && image?.property) ? 'class1' : 'class2'"
Safe navigation operator checks if a property is defined before trying to access it.
Update
OP's requirement - use neither of the classes if image?.isAvailable is undefined.
You could extend the ternary operator to one more level to check if image?.isAvailable is defined before applying the classes.
[ngClass]="image?.isAvailable ? (image?.property ? 'class1' : 'class2') : ''"
The empty string '' denotes empty class list if image?.isAvailable property is undefined.

This can be written like this:
[ngClass]="{
'class1':
image.isAvailable && !image.property),
'class2':
image.isAvailable && image.property)
}"
Also you can write like this:
[class.class1]="image.isAvailable && !image.property"
[class.class2]="image.isAvailable && image.property"

Related

Why do I get these errors with my ternary operator?

This is what I get in the console: Unnecessary use of boolean literals in conditional expression no-unneeded-ternary.
I'm just trying to do a ternary operator that validates the state of a game and only if the game has started and the user.role is equal with player I disable the button. I am using reactjs and with the help of FormField hook I am making a form.
disabled ={(game.state === 'started' && user.role === PLAYER) ? true : false}
The ternary operator is unnecessary:
disabled ={(game.state === 'started' && user.role === PLAYER)}
No need to use statements in this case, ESlint is letting you know it's redundant since the value produced from this statement is already a boolean and you can create a simpler code.
Just write:
disabled = {(game.state === 'started' && user.role === PLAYER)}

How can I do to put a value by default for the map function?

I am using React.js and I
myArray.map(variable=>({value: variable.value, label: variable.label}))
everything is ok but sometimes I have the following case : TypeError : myArray is null
How can I do to put a default value or something like this ?
Thank you very much !
To avoid this error, you have to to implement a check before you run the map function.
If you are doing it outside JSX, as it seems in your code then the code should look like:
if (myArray && myArray.length > 0) {
myArray.map(variable=>({value: variable.value, label: variable.label}))
}
And if you are doing it inside JSX, then the code should look like:
myArray && myArray.length > 0 && myArray.map((...your code...))
Extending Shafayet's answer,
If you're using es6, you can use optional chaining. Like this:
myArray?.map(variable=>({value: variable.value, label: variable.label}))
Not the best solution but works with OR (||) operator when myArray is null:
(myArray || []).map(variable=>({value: variable.value, label: variable.label}))

ReactJs SyntaxError with ternary operator

Below code shows syntax error in ReactJs component:
(that.props.actionType == "opinion")
?
{that.state._CmtCnt?<ViewAnswer isFullView={that.props.isFullView?true:false} />:null}
:
{that.state._CmtCnt?<ViewComment isFullView={that.props.isFullView?true:false} />:null}
Basic Syntax is:
condition? expression1 : expression2
This is because you are using {} with expression1 and expression2, remove that, {} is required when we want to put JS expressions inside JSX. The way you are using, it means you are trying to return an object and error is because key is not valid.
Write it like this:
(that.props.actionType == "opinion") ?
(that.state._CmtCnt?<ViewAnswer isFullView={that.props.isFullView?true:false} />:null)
:
(that.state._CmtCnt?<ViewComment isFullView={that.props.isFullView?true:false} />:null)
You need to use normal parenthesis for grouping. Braces work only within jsx expressions.
that.props.actionType == "opinion"
? (that.state._CmtCnt ? <ViewAnswer isFullView={that.props.isFullView} /> : null)
// ^ ^
: (that.state._CmtCnt ? <ViewComment isFullView={that.props.isFullView} /> : null)
// ^ ^
You should write easier to understand code rather than complex nested terinary with little changes between them - all you choose is pick up a component to use, so move that up and you end up with easier to read code with less logic inside JSX
const Renderer = that.props.actionType == "opinion" ? ViewAnswer : ViewComment
// ...
{that.state._CmtCnt && <Renderer isFullView={!!that.props.isFullView} />}
// or
{that.state._CmtCnt ?
<Renderer isFullView={!!that.props.isFullView} /> :
null
}
not sure why you are using that either - aliases for context such as self or that are a bit out of date, you tend to want to keep context to your instances and bind correctly

How to make true && false equal to true in angularjs expression?

I'm trying to check if an input has been touched and is empty (without the built in functions in angular).
<form-input is-invalid-on="isTouched && !gs.data.name || gs.data.name.length > 50"></form-input>
If isTouched && !gs.data.name evaluates to true && false then that side of the expression becomes false
So my question is quite simple, how do I make the entire expression evaluate to true if the input has been touched and if it's empty or has a length greather than 50?
I believe it is used as attribute directive.
is-invalid-on="(isTouched && gs.data.name.length) || gs.data.name.length > 50"
Reason? I assumed your gs.data.name is a string. Empty string when evaluated in javascript is still a truthy value. So you must evaluate it to length.
<form-input is-invalid-on="(isTouched && !gs.data.name) || (gs.data.name.length > 50)"</form-input>
can try using () and also check gs.data like isTouched && (!gs.data || !gs.data.name || !gs.data.name.length || gs.data.name.length > 50)
<form-input is-invalid-on="isTouched && (!gs.data || !gs.data.name || !gs.data.name.length || gs.data.name.length > 50)"></form-input>
Angular expression does not work exactly the same than javascript from what i got try this one :
<form-input is-invalid-on="isTouched && gs.data.name.length==0 || gs.data.name.length > 50"></form-input>
Assuming you properly initialized gs.data.name to empty string.
By the way you forgot the > on your tag.
I finally found the reason as to why it was behaving so strange, and as this question has many answers I could not delete it. So I might as well explain what happened.
It turned out that isTouched was always undefined because I was using it outside of the directive (even if it was used in an attribute of the directive) which made the expression undefined && false, resulting in isInvalidOn always being false.
Instead I made it so that I used isTouched later in the actual form-input template as ng-class={invalid: isInvalidOn && isTouched}, resulting in the desired behavior.

Angular ternary expression that runs more than one line of code

so I have this example of code,
in one of my forms, it works perfectly.
ng-submit="
commentCtrl.edit(comment.id, comment.text);
comment.edit=false;
"
on the other hand, when I try to run multiple "commands" in a ternary ng-keyup, things go wrong, angular can't parse it.
ng-keyup="
($event.keyCode == 13 && !$event.shiftKey)
?
commentCtrl.edit(comment.id, comment.text);comment.edit=false
:
return"
also tried:
($event.keyCode == 13 && !$event.shiftKey)
?
commentCtrl.edit(comment.id, comment.text) && comment.edit=false
:
return"
help me please!
It's a bad practice to write such expressions inside of markup.
Anyway you can do it by putting the values into an array:
ng-submit="[commentCtrl.edit(comment.id, comment.text), comment.edit=false]"
ng-keyup="($event.keyCode == 13 && !$event.shiftKey)
? [commentCtrl.edit(comment.id, comment.text), comment.edit=false]
: 0"

Categories

Resources