Q:

Object property is undefined in AngularJS

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?

A:

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.

