2

The following works for me:

HTML:

{{user.uid}}

JS:

"use strict";

app.controller('Ctrl', function($scope, Auth) {

$scope.user = Auth.user;
});

but

HTML:

{{uid}}

JS:

app.controller('Ctrl', function($scope, Auth) {
 $scope.uid = Auth.user.uid;
});

doesn't work, and it's because Auth.user.uid is undefined! Why is this happening? Why can we call attributes within the view but not within the controller? What should I do if i want to call an attribute within the controller?

4
  • 2
    does Auth.user return a promise? Commented Oct 21, 2015 at 0:22
  • @Claies my guess is something somewhere else is populating Auth.user asynchronously. It wouldn't be a promise itself Commented Oct 21, 2015 at 0:26
  • @Phil yes, like a promise from $http. either way, without seeing the code for Auth, we can only guess at the real issue. Commented Oct 21, 2015 at 0:27
  • My bad guys - I'm pretty sure I have the same problem as in here: stackoverflow.com/questions/25450325/… - should I delete this question? Commented Oct 21, 2015 at 0:28

1 Answer 1

4

This is likely to occur because at the time you assign Auth.user.uid to the scope, that attribute does not exist. It is assigned at a later time to the user object, but because you have mapped the value directly to $scope, it won't update the way you would like it to. Here is an example of how this could happen:

.service('Auth', function($http){
    this.user = {};
    // this server call takes some amount of time to complete,
    // and until it does user.uid is undefined
    var self = this;
    $http.get('http://someurl', function(result){
        self.user.uid = result.uid;
    });
});

.controller('MyCtrl', function($scope, Auth){
    // this is called before the $http call is completed inside Auth
    $scope.uid = Auth.user.uid;

    // this is also called before the $http call completed, but because user exists, its children cause a scope change and notification
    $scope.user = Auth.user;
});

Now the way you have it working, by binding the user object to the scope is a much better way of doing it anyway. It is good practice to only bind container objects to $scope.

Sign up to request clarification or add additional context in comments.

3 Comments

Just to clarify, it's the $http promise resolution that trigger the digest cycle, thus updating the template. JavaScript's object referencing means Auth.user is the same object as $scope.user
Just wondering - why is it good practice to only bind container objects to $scope?
Primarily because you guarantee the $scope level that you are trying to access (essential for things like ng-model too). Just research how angular scope hierarchies work, and why a dot is important.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.