I'm trying to get my parent / child view templates to render a value that should be populated in it's parent route in ui.router, but I'm too new to the process to understand where I've done wrong.
I have a nav bar that contains a username, and a profile page that displays all the user data in forms. I thought that using resolve in the route would pre-populate the data object in the controller, but something is off, because my input fields are capable of populating the "ng-model" inputs with the right user information from the same object, but all the places I try to use the {{}} tags in my HTML templates don't resolve.
Factory:
myApp.factory('userFactory', function($http, $q) {
var service = {};
delete $http.defaults.headers.common['X-Requested-With'];
service.getCurrentUser = function() {
var deferred = $q.defer();
$http.get('/getmyuser') // returns a user Object, with "name", "profileImage", etc
.success(function(response) {
deferred.resolve(response);
}).error(function(err) {
deferred.reject(err);
});
return deferred.promise;
}
return service;
});
Controller:
function UserCtrl($scope, currentUser, userFactory) {
$scope.currentUser = currentUser.currentUser;
$scope.isLoggedIn = function() { // Works when checked in the same template as the elements that do not work.
if ($scope.currentUser) return true;
else return false;
}
$scope.isAdmin = function() { // When I check this with ng-show, it works.
if ($scope.currentUser) {
var roles = $scope.currentUser.roles;
for (index = 0; index < roles.length; ++roles) {
if (roles[index].name == "admin") return true;
}
}
return false;
}
}
The module:
var myApp = angular.module('myApp', ['ui.router'])
.controller('userCtrl', ['$scope', 'currentUser', 'userFactory', UserCtrl])
.config(function ($stateProvider,$urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$stateProvider
.state('core', {
url: '',
abstract:true,
resolve: {
userFactory: 'userFactory',
currentUser: function(userFactory) {
return userFactory.getCurrentUser().then(function(response) {
return { currentUser: response };
});
}
},
views: {
"nav@": {
templateUrl: '/api/v1/partials/nav',
controller: 'userCtrl'
}
}
})
.state('core.profile', {
url: '/profile',
views: {
"contentArea@core": {
templateUrl: '/api/v1/partials/profile'
}
}
});
});
HTML file 1 (index.html, being served as an ng-include inside a valid HTML wrapping with header section, body section, source includes for angular, etc):
<div ui-view="nav"></div>
HTML file 2 (nav.html, most of it being omitted, as it's a standard bootstrap nav skeleton ... portion of interest added. There are no ng-controller assignment anywhere in my documents, as this breaks the resolve injections):
<li ng-show="isLoggedIn()"> <!-- This works -->
<a ui-sref="core.profile">
Welcome, {{currentUser.name}}! <!-- This does not -->
</a>
</li>
<!-- ... more code until the end of the nav bar -->
<div ui-view="contentArea"></div>
There's a profile page as well that's a child, but the inputs are working on that one without me having to include anything extra, however none of the {{}}s are resolved on that page either, regardless of the inputs working automagically. I thought placing all my initialization code in a resolve block would solve this, but obviously I'm missing something.
Any help would be greatly appreciate!
EDIT: Turns out that ng-include (which I was using as my way of breaking up the app into smaller templates) was creating independent scopes that had nothing to do with userCtrl, unless you wanted to refer to it as "$parent" or drop things into $rootScope.
I restructured the app to not use ng-include, and now I can access my bindings via ng-bind and regular ol' $scope, instead of using $rootScope or bothering with ng-includes independent scoping. Thanks to everyone for reviewing that, and sorry for the wild goose chase in the wrong direction.