ng-class evaluates to wrong classname

208 views Asked by At

In my angular app I have some HTML with angulars ng-class directive:

<button type="button" class="btn" ng-class="{true:'btn-success', false:'btn-danger'}[status.isSoftware()]">
    <span>{{status.isSoftware()}}</span>
</button>

This evaluates to:

<button type="button" class="btn btn-success" ng-class="{true:'btn-success', false:'btn-danger'}[status.isSoftware()]">
    <span>false</span>
</button>

As you can see, ng-class evaluates the expression to true and assigns .btn-success to my button while the span evaluates the same expression to false (what is the expexted behaviour). I debugged the function and it always returns false (as it should).

How is this even possible? I have quite similar statements throughout my application and everywhere else it works fine.

Someone has any idea? What am I missing here? What could cause the problem?

EDIT (reduced code sample):

angular.module("abc", [])
.factory("StatusService", [
"APP_MODEL",
    function (APP_MODEL) {

        var m_Model = {
                Software : false,
                Locked   : false
            },

            m_Status = {
                isSoftware  : function () {
                    return m_Model.Software && !m_Model.Locked;
                },
                isHardware  : function () {
                    return !m_Model.Software && !m_Model.Locked;
                },
                isLocked    : function () {
                    return m_Model.Locked;
                }
            },

            listenToServerUpdates = function () {
                //
                APP_MODEL.Software.addServerUpdateCallback(function (value) {
                    m_Model.Software = value == 1;
                });

                //
                APP_MODEL.Locked.addServerUpdateCallback(function (value) {
                    m_Model.Locked = value == 1;
                });
            };

        listenToServerUpdates();

        return {
            status : m_Status
        };
    }
])
.controller("ABCtrl", [
    "$scope",
    "StatusService",
    function ($scope, service) {
        $scope.status = service.status;
    }
]);
1

There are 1 answers

6
alesc On

As per documentation, you should use ng-class in the following matter.

Instead of:

ng-class="{true:'btn-success', false:'btn-danger'}[status.isSoftware()]"

You should use:

ng-class="{'btn-success' : status.isSoftware(), 'btn-danger': !status.isSoftware()}"

EDIT: However, I am not sure if using a function call will work. Therefore I would recommend using a property instead of a function call.

EDIT 2: Apparently it works. Thanks for all the input from the comments.