Oam Psy
Oam Psy

Reputation: 8663

ng-if, not equal to?

I have a simple ng-reapt that displays a list of values.. On some of the outputs, i have a couple of ng-if to show/hide DIVs.

HTML:

<div ng-repeat="details in myDataSet">

    <p>{{ details.Name }}</p>
    <p>{{ details.DOB  }}</p>

       <div ng-if="details.Payment[0].Status == '0'">
           <p>No payment</p>
       </div>

       <div ng-if="details.Payment[0].Status == '1' || details.Payment[0].Status == '2'">
           <p>Late</p>
       </div>

       <div ng-if="details.Payment[0].Status == '3' || details.Payment[0].Status == '4' || details.Payment[0].Status == '5'">
           <p>Some payment made</p>
       </div>

       <div ng-if="details.Payment[0].Status == '6'">
           <p>Late and further taken out</p>
       </div>

       <div ng-if="details.Payment[0].Status != '0' || details.Payment[0].Status != '1' || details.Payment[0].Status != '2' || details.Payment[0].Status != '3' || details.Payment[0].Status != '4' || details.Payment[0].Status != '5' || details.Payment[0].Status != '6'">
           <p>Error</p>
       </div>

    <p>{{ details.Gender}}</p>

</div>

My application is displaying an error when attempting to display the != section.

Upvotes: 17

Views: 177488

Answers (8)

omikes
omikes

Reputation: 8533

This is now possible as of AngularJS 1.5.10, using ng-switch-when-separator

var app = angular.module("app", []); 

app.controller("ctrl", function($scope) {
    $scope.myDataSet = [{Name: 'Michelle', Gender: 'Female', DOB: '01/12/1986', Payment: [{Status: '0'}]},{Name: 'Steve', Gender: 'Male', DOB: '11/12/1982', Payment: [{Status: '1'}]},{Name: 'Dan', Gender: 'Male', DOB: '03/22/1976', Payment: [{Status: '2'}]},{Name: 'Doug', Gender: 'Male', DOB: '02/02/1980', Payment: [{Status: '3'}]},{Name: 'Mary', Gender: 'Female', DOB: '04/02/1976', Payment: [{Status: '4'}]},{Name: 'Cheyenne', Gender: 'Female', DOB: '07/10/1981', Payment: [{Status: '5'}]},{Name: 'Bob', Gender: 'Male', DOB: '02/16/1990', Payment: [{Status: '6'}]},{Name: 'Bad data', Gender: 'Blank', DOB: '01/01/1970', Payment: [{Status: '7'}]}];
});
<script src="https://code.angularjs.org/1.5.10/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
    <div ng-repeat="details in myDataSet" ng-switch on="details.Payment[0].Status">

        <p>{{ details.Name }}</p>
        <p>{{ details.DOB  }}</p>

        <div ng-switch-when="0">
            <p>No payment</p>
        </div>

        <div ng-switch-when="1|2" ng-switch-when-separator="|">
            <p>Late</p>
        </div>

        <div ng-switch-when="3|4|5" ng-switch-when-separator="|">
            <p>Some payment made</p>
        </div>

        <div ng-switch-when="6">
            <p>Late and further taken out</p>
        </div>

        <div ng-switch-default>
            <p>Error</p>
        </div>
        
        <p>{{ details.Gender}}</p>

    </div>
</div>

Upvotes: 0

Dmitry Belyaev
Dmitry Belyaev

Reputation: 2593

There are pretty good solutions here but they don't help to understand why the problem actually happens.

But it's very simple, you just need to understand how logic OR || works. Whole expression will evaluate to true when either of its sides evaluates to true.

Now let's look at your case. Assume whole details.Payment[0].Status is Status and it's a number for brevity. Then we have Status != 0 || Status != 1 || ....

Imagine Status = 1:

( 1 != 0 || 1 != 1 || ... ) =
(  true  || false  || ... ) =
(       true       || ... ) = ... = true

Now imagine Status = 0:

( 0 != 0 || 0 != 1 || ... ) =
( false  ||  true  || ... ) =
(       true       || ... ) = ... = true

As you it doesn't even matter what you have as ... as logical OR of first two expressions gives you true which will be the result of the full expression.

What you actually need is logical AND && that will be true only if both its sides are true.

Upvotes: 0

Mohd Asif
Mohd Asif

Reputation: 31

Try below solution

ng-if="details.Payment[0].Status != '0'"

Use below condition(! prefix with true condition) instead of above

ng-if="!details.Payment[0].Status == '0'"

Upvotes: 3

Tom Stickel
Tom Stickel

Reputation: 20431

I don't like "hacks" but in a quick pinch for a deadline I have done this

<li ng-if="edit === false && filtered.length === 0">
    <p ng-if="group.title != 'Dispatcher News'" style="padding: 5px">No links in group.</p>
</li>

Yes, I have another inner nested ng-if, I just didn't like too many conditions on one line.

Upvotes: 1

maurycy
maurycy

Reputation: 8465

That's all unnecessary logic in partials, reduce it to something like this and process your data in controller/service where it should be

<div ng-repeat="details in myDataSet">

    <p>{{ details.Name }}</p>
    <p>{{ details.DOB  }}</p>
    <p>{{details.Payment[0].StatusName}}</p>
    <p>{{ details.Gender}}</p>

</div>

JS:

angular.forEach(myDataSet.Payment, function (payment) {
  if(payment.Status === 0){
    payment.StatusName = 'No Payment';
  } else if(payment.Status === 1 || payment.Status === 2){
    payment.StatusName = 'Late';
  } else if(payment.Status === 3 || payment.Status === 4 || payment.Status === 5){
    payment.StatusName = 'Some payment made';
  } else if(payment.Status === 6){
    payment.StatusName = 'Late and further taken out';
  }else{
    payment.StatusName = 'Error';
  }
})

Upvotes: 3

Alagarasan M
Alagarasan M

Reputation: 907

Try this:

ng-if="details.Payment[0].Status != '6'".

Sorry about that, but I think you can use ng-show or ng-hide.

Upvotes: 3

Ilan Frumer
Ilan Frumer

Reputation: 32397

Here is a nifty solution with a filter:

app.filter('status', function() {

  var statusDict = {
    0: "No payment",
    1: "Late",
    2: "Late",
    3: "Some payment made",
    4: "Some payment made",
    5: "Some payment made",
    6: "Late and further taken out"
  };

  return function(status) {
    return statusDict[status] || 'Error';
  };
});

Markup:

<div ng-repeat="details in myDataSet">
  <p>{{ details.Name }}</p>
  <p>{{ details.DOB  }}</p>
  <p>{{ details.Payment[0].Status | status }}</p>
  <p>{{ details.Gender}}</p>
</div>

Upvotes: 12

Charnjeet Singh
Charnjeet Singh

Reputation: 3107

It is better to use ng-switch

<div ng-switch on="details.Payment[0].Status">
    <div ng-switch-when="1">
        <!-- code to render a large video block-->
    </div>
    <div ng-switch-default>
        <!-- code to render the regular video block -->
    </div>
</div>

Upvotes: 13

Related Questions