ngClass if statement multiple expressions not working - angularjs

I would like to give the the class 'bg-green' to the div when 'task.taskChecked' is true. This works, and also when 'task.taskDescription' has the word 'afspraak' the class should be 'bg-purple' this also works.
But with what I am struggling is, when 'task.taskChecked'is true AND 'task.taskDescription' contains the word 'afspraak' also give it the class 'bg-green'
Here is the code:
<div class="tableCell taskIndicator" data-ng-class="{'bg-green': task.taskChecked == true || ( task.taskChecked == true && task.taskDescription.toLowerCase().indexOf('afspraak') > -1 ), 'bg-red': task.taskChecked == false, 'bg-purple': task.taskDescription.toLowerCase().indexOf('afspraak') > -1}">
</div>
SOLUTION:
<div class="tableCell taskIndicator" data-ng-class="{'bg-green': task.taskChecked, 'bg-red': task.taskChecked == false, 'bg-purple': task.taskDescription.toLowerCase().indexOf('afspraak') > -1&&!task.taskChecked}">
</div>

order is important while writing your expression.
<div class="tableCell taskIndicator" data-ng-class="{'bg-red':
task.taskChecked == false, 'bg-purple':
task.taskDescription.toLowerCase().indexOf('afspraak') > -1,
'bg-green': task.taskChecked == true || ( task.taskChecked == true &&
task.taskDescription.toLowerCase().indexOf('afspraak') > -1 )}">
</div>

Related

ReactJS complex (if / else if) not working as expected

I have the following conditional
if (
!user.userId
&& match.path === '/login'
) {
component = <Login/>
} else if (
user.userId
&& !user.OTPVerified
&& !user.loginWithPassword
&& match.path === '/verify'
) {
component = <VerifyOTP/>
} else if (
(user.userId && user.OTPVerified) || (user.userId && user.loginWithPassword)
&& !user.profileCompleted
&& match.path === '/complete-profile'
) {
console.log('userid', user.userId)
console.log('otpverified', user.OTPVerified)
console.log('loginWithPassword', user.loginWithPassword)
console.log('profileCompleted', user.profileCompleted)
console.log('path', match.path)
component = <CompleteProfile/>
} else if (
user.userId
&& !user.OTPVerified
&& user.loginWithPassword
&& user.profileCompleted
&& match.path === '/login-password'
) {
component = <LoginWithPassword/>
} else {
component = <Login/>
}
console returns
userid 29
otpverified true
loginWithPassword false
profileCompleted true
path /login
I dont get why am i still seeing CompleteProfile component
Add some parenthesis around those two expressions with the || between them if they should be evaluated together.
((user.userId && user.OTPVerified) || (user.userId && user.loginWithPassword))
This change makes your Login component show based on the values.
You can remove the inner ones too and the && will be evaluated first.
(user.userId && user.OTPVerified || user.userId && user.loginWithPassword)
else if (
(user.userId && user.OTPVerified || user.userId && user.loginWithPassword)
&& !user.profileCompleted
&& match.path === '/complete-profile'
)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND#Operator_precedence
console.log((true && true) || (true && false) && false && false) //true
console.log((true && true || true && false) && false && false) // false

convert this multiple condition into ng-class conditional

Hello there I need help in converting this 'if-else' with 'or' condition into conditon that can be used in ng-class.
This here is my ng-class with condition, but it's not working correctly.
<span ng-class="{'green': work > toWork,
'red': work < toWork,
'black': work == toWork || overall == '-'}">
{{overall = showMonthly(work = (workers | getMonthValue: dts.value),
toWork = getMonthlyToWork(member.id, dts.value))}}
</span>
this is the condition I'd like to apply:
if (work > toWork) {
return "green";
}else if (work < toWork) {
return "red";
}else if (work == toWork || overall == "-") {
return "black";
}
You don't need ng-class for that, you just need to put the logic inside a method in your $scope, like below
$scope.getClass = function(work, toWork, overall){
if (work == toWork || overall == "-"){
return "black";
}else if (work < toWork) {
return "red";
}else if(work > toWork) {
return "green";
}
}
and in your view, call it like this
<span class="{{getClass(work, toWork, overall)}}"></span>
<span ng-class="{'green': work > toWork,
'red': work < toWork,
'black': (work == toWork || overall == '-')}">
...
</span>
Check this. (You have got a spell missing in your conditional statement)
Happy coding!

ng-show expression: comparing multiple strings using ||

Can someone please explain why this works:
<div ng-repeat="fruit in fruits">
<span ng-hide="fruit.type == 'apple' || fruit.type == 'banana'">
{{fruit.type}}
</span>
</div>
Renders:
pear lemon
But this doesn't:
<div ng-repeat="fruit in fruits">
<span ng-hide="fruit.type == 'apple' || 'banana'">
{{fruit.type}}
</span>
</div>
Renders:
// nothing
In Javascript (and most languages I know), comparisons aren't communicable. For every comparison (in this case equality), you unfortunately need a full statement.
In fruit.type == 'apple' || 'banana',
1. fruit.type == 'apple' is evaluated.
2. After that, it || compares the result of that to 'banana', which in Javascript is a truthy value ('' is the only "falsy" string, all other strings are "truthy").
In essence, you end up with fruit.type == 'apple' || TRUE, which will always trigger ng-hide.
in this case its a bad expression fruit.type == 'apple' || 'banana'
|| are used in javascript for "OR" and define a default value to a variable when some reference values is undefined or null for example:
var name = null || "mottaman85";
consolog.log(name);
"mottaman85"
function test(nombreV){
var name = nombreV || "mottaman85";
console.log(name)
}
test();
"mottaman85"

'ng-if' - Multiple condition not working on template

I have 3 variety of template. by $index conditionally i am applying the template.
here is my directive html :
<all-apps-gallery index="$index" app="app" update="update(app)" class="show" ng-repeat="app in allAppsBatch"></all-apps-gallery>
and here is the directive:
var allAppsGallery = function ($compile, $animate) {
return {
restrict : 'E',
replace : true,
templateUrl : '/views/tools/gallery.html', // see below the html
scope : {
index : "=",
update : "&",
app : "="
}
}
}
}
angular
.module("tcpApp")
.directive('allAppsGallery', allAppsGallery);
My `templateUrl''s html :
<div>
<div ng-class="bgr box{{index}}" ng-click="update(app)" ng-if="{{index}} == 0 || {{index}} == 13 || {{index}} == 14 || {{index}} == 15 || {{index}} == 5 ">
<h2>{{app.completion}} % {{index}}</h2>
<span>{{app.name}}</span>
</div>
<div ng-class="bbr box{{index}}" ng-click="update(app)" ng-if="{{index}} == 2 || {{index}} == 3 || {{index}} == 4 || {{index}} == 6 || {{index}} == 10 || {{index}} == 11 || {{index}} == 12">
<h2>{{app.completion}} %</h2>
<span>{{app.name}}</span>
</div>
<div ng-class="bbl box{{index}}" ng-click="update(app)" ng-if="{{index}} == 1 || {{index}} == 7 || {{index}} == 8 || {{index}} == 9 ">
<h2>{{app.completion}} %</h2>
<span>{{app.name}}</span>
</div>
</div>
Here according to the index value, i am switching the template. but it's not working for me. what is the wrong i made here?
Any one figure-out me please?
Thanks in advance.
I am getting this error:
Error Link
ngIf directive expects an expression, and hence you don't need to have interpolation tags {{ }} in it. Attribute value will be parsed and evaluated by Angular, however {{ tags make value an invalid JS expression and cannot be processed.
Correct code would be
ng-if="index == 0 || index == 13 || index == 14 || index == 15 || index == 5 "

Why am I getting different results from ng-show="!emptyArray" and ng-hide="emptyArray"?

I have always thought ngShow and ngHide act as boolean counterpart to each other. That belief, however, is shaken by the unexpected behaviour of ngShow when an empty array is involved.
Here is a demo plunker. Why isn't ng-show="!emptyArray" behaving like ng-hide="emptyArray"?
Because [] !== false. You can coerce the length value to boolean instead with !!.
<div ng-hide="!!emptyArray.length">emptyArray is falsy, so do not hide this.</div>
<div ng-show="!!!emptyArray.length">!emptyArray is truthy, so show this.</div>
Edited:
AngularJS's directive hide or show depends on the function toBoolean() for evaluating the value passed in. Here is the source code of toBoolean():
function toBoolean(value) {
if (value && value.length !== 0) {
var v = lowercase("" + value);
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
} else {
value = false;
}
return value;
}
And you can verify the following code in JS console:
>var emptyArray = [];
>toBoolean(emptyArray)
false
>toBoolean(!emptyArray)
false
That explains why. Since when emptyArray is passed to the toBoolean() directly, it evaluates the correct result false. However when !emptyArray is passed to toBoolean(), it doesn't evaluate to true since !emptyArray is false itself.
Hope it helps.
ng-if and ng-show mistreats "[]" (empty array)
See: this link
[] == true
false
[] != true
true
(![]) == true
false
[''] == true
false
(!['']) == true
false
"" == true
false
"[]" == true
false
(!"[]") == true
false
Sounds its by design.
I use something like this , it works to me
ng-hide="array.length == 0"

Resources