admin管理员组

文章数量:1426597

I have a user on the current scope, set by my current controller.

$scope.user = user;

Selectively showing/hiding a <div> based on the existence of this user is not working as I would expect, rather an exception is being thrown.

Does not work: ng-show="user"

<div class='row' ng-show="user">
    ...
</div>

Works: ng-show="!!user"

<div class='row' ng-show="!!user">
    ...
</div>

What is happening with ng-show which results in ng-show="user" not being truthy?

I am using angular.1.2.6 from .2.6/angular.min.js

Exception thrown:

If I use ng-show="user", then I get the following exception in my console:

TypeError: Cannot convert object to primitive value
    at Ma (.2.6/angular.min.js:14:240)
    at Object.<anonymous> (.2.6/angular.min.js:185:464)
    at Object.applyFunction [as fn] (<anonymous>:778:50)
    at h.$digest (.2.6/angular.min.js:99:211)
    at h.$delegate.__proto__.$digest (<anonymous>:844:31)
    at .2.6/angular.min.js:101:256
    at e (.2.6/angular.min.js:33:182)
    at .2.6/angular.min.js:36:378 

This error disappears when I use ng-show="!!user"

User object:

This is the user object which is on the $scope:

{
  "state": "",
  "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "token_type": "Bearer",
  "expires_in": "3600",
  "code": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "scope": ".login .email .moments.write .me .profile.agerange.read .profile.language.read .circles.members.read",
  "id_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "authuser": "0",
  "session_state": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "prompt": "none",
  "client_id": "xxxxxxxxxxx.apps.googleusercontent",
  "g_user_cookie_policy": "single_host_origin",
  "cookie_policy": "single_host_origin",
  "response_type": "code token id_token gsession",
  "issued_at": "1391059385",
  "expires_at": "1391062985",
  "_aa": "0",
  "status": {
    "google_logged_in": true,
    "signed_in": true,
    "method": "AUTO"
  }
}

I have a user on the current scope, set by my current controller.

$scope.user = user;

Selectively showing/hiding a <div> based on the existence of this user is not working as I would expect, rather an exception is being thrown.

Does not work: ng-show="user"

<div class='row' ng-show="user">
    ...
</div>

Works: ng-show="!!user"

<div class='row' ng-show="!!user">
    ...
</div>

What is happening with ng-show which results in ng-show="user" not being truthy?

I am using angular.1.2.6 from https://ajax.googleapis./ajax/libs/angularjs/1.2.6/angular.min.js

Exception thrown:

If I use ng-show="user", then I get the following exception in my console:

TypeError: Cannot convert object to primitive value
    at Ma (https://ajax.googleapis./ajax/libs/angularjs/1.2.6/angular.min.js:14:240)
    at Object.<anonymous> (https://ajax.googleapis./ajax/libs/angularjs/1.2.6/angular.min.js:185:464)
    at Object.applyFunction [as fn] (<anonymous>:778:50)
    at h.$digest (https://ajax.googleapis./ajax/libs/angularjs/1.2.6/angular.min.js:99:211)
    at h.$delegate.__proto__.$digest (<anonymous>:844:31)
    at https://ajax.googleapis./ajax/libs/angularjs/1.2.6/angular.min.js:101:256
    at e (https://ajax.googleapis./ajax/libs/angularjs/1.2.6/angular.min.js:33:182)
    at https://ajax.googleapis./ajax/libs/angularjs/1.2.6/angular.min.js:36:378 

This error disappears when I use ng-show="!!user"

User object:

This is the user object which is on the $scope:

{
  "state": "",
  "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "token_type": "Bearer",
  "expires_in": "3600",
  "code": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "scope": "https://www.googleapis./auth/plus.login https://www.googleapis./auth/userinfo.email https://www.googleapis./auth/plus.moments.write https://www.googleapis./auth/plus.me https://www.googleapis./auth/plus.profile.agerange.read https://www.googleapis./auth/plus.profile.language.read https://www.googleapis./auth/plus.circles.members.read",
  "id_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "authuser": "0",
  "session_state": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "prompt": "none",
  "client_id": "xxxxxxxxxxx.apps.googleusercontent.",
  "g_user_cookie_policy": "single_host_origin",
  "cookie_policy": "single_host_origin",
  "response_type": "code token id_token gsession",
  "issued_at": "1391059385",
  "expires_at": "1391062985",
  "_aa": "0",
  "status": {
    "google_logged_in": true,
    "signed_in": true,
    "method": "AUTO"
  }
}
Share Improve this question edited Jan 30, 2014 at 5:26 Steve Lorimer asked Jan 30, 2014 at 4:54 Steve LorimerSteve Lorimer 28.8k21 gold badges133 silver badges236 bronze badges 4
  • 1 can you provide an example of the failure. Seems to work for me. jsfiddle/pMFjL – hassassin Commented Jan 30, 2014 at 4:58
  • $scope.user is being set on a Google+ oauth2 callback, which I can't replicate on jsfiddle/plunker etc – Steve Lorimer Commented Jan 30, 2014 at 5:16
  • @hassassin - added the TypeError exception to the question – Steve Lorimer Commented Jan 30, 2014 at 5:21
  • Opened angular issue: github./angular/angular.js/issues/6051 – Steve Lorimer Commented Jan 30, 2014 at 5:50
Add a ment  | 

2 Answers 2

Reset to default 6

Keep in mind that ngShow expects an expression to evaluate and will "convert" to Boolean using this function:

function toBoolean(value) {
  if (typeof value === 'function') {
    value = true;
  } else 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;
}

https://github./angular/angular.js/blob/834d316829afdd0cc6a680f47d4c9b691edcc989/src/Angular.js#L962

So you shouldn't just use an object. You could keep using !!user or maybe user.someattr

The !! operator basically converts the JS object to a boolean.

Check out the following example:

function myCtrl($scope) {
    $scope.user = 'false';
    $scope.boolean = !!$scope.user;
}

We create a user object, containing for example the string false, and it's boolean representation by calling the !! operator. Since $scope.user has a value that is not null, the !! operator will convert it to true. However angular will convert the string 'false' to the boolean value false, and thus hide the div.

We can test this in the following way:

<div ng-controller="myCtrl">
    <div ng-show="boolean">
        test boolean
    </div>

    <div ng-show="user">
        test user
    </div>

    <span>{{boolean}}</span>
</div>

Which outputs the following:

test boolean
true

http://jsfiddle/FTXn3/

@EDIT

Since we are talking about a user object and not a string, as stated by the error message you receive, the !! does the conversion to the boolean (=primitive) for you.

本文标签: javascriptAngularJS ngshowquotuserquot falseyngshowquotuserquot truthyStack Overflow