bluedevil2k bluedevil2k - 1 month ago 8
AngularJS Question

Angular - $rootScope variables

In my Angular 1.5 app (a SPA), I use user profile information on every "page" of the app. So, in my app.js file, I include the following code:

$http.get(API_URL + "/user")
.then(function success(response){
$rootScope.userInfo = response.data;
},
function error(response){

});


And then in each component's controller and template, I make reference to this object like the following:

<img class="profile icon" ng-src="{{$rootScope.userInfo.profile_photo}}">


However, the image never shows up. I assume because the callback setting the $rootScope.userInfo from the response is called after the template has been loaded. How do I ensure it gets updated when the response comes in from the GET call?

EDIT - Here's more info, since the answers coming in about "don't use $rootScope in the view" isn't working for me. Making the changes suggested doesn't work. Do I need to reference $ctrl in this case?

angular.module('xxx')
.component("navBar", {
templateUrl: "/components/navBar/navBar.html",
controller: NavBarController,
bindings: {

}
});

function NavBarController($rootScope, $scope, $uibModal, $timeout, $http, API_URL) {
var vm = this;

Answer

Remember that the view is bound to the $scope already, you never write the following

<img class="profile icon" ng-src="{{$scope.userInfo.profile_photo}}">

instead

<img class="profile icon" ng-src="{{userInfo.profile_photo}}">

All scopes, except isolate scopes, have inheritance and the $rootScope is at the top of that chain, so as long as no other $scope have a userInfo property in that chain writting

<img class="profile icon" ng-src="{{userInfo.profile_photo}}">

will point to the property in the $rootScope

If you are inside a isolate scope you could write

<img class="profile icon" ng-src="{{$root.userInfo.profile_photo}}">

since all scopes, even isolated, have a $root property that points to the $rootScope

Check here

angular.module('app', [])
  .controller('TestCtrl', function($scope) {
    // An empty controller to create a new scope
    // Only for demonstration of inheritance 
  })
  .directive('directive', function() {
    return {
      restrict: 'E',
      scope: {},
      template: '<div>{{$root.userInfo.name}}</div>'
    };
  })
  .run(function($rootScope) {
    $rootScope.userInfo = {
      name: 'John'
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div>{{userInfo.name}}</div>
  <div ng-controller="TestCtrl">
    {{userInfo.name}}
  </div>
  <directive></directive>
</div>

Comments