Search code examples
javascriptangularjsangular-ui-router

Checking if parent state promise has returned value


Using AngularJS and ui-router to create states and I have a parent and child state.

    .state('portfolio', {
        url: '/portfolio',
        templateUrl: 'app/templates/portfolio/portfolio.tpl.htm',
        controller: 'portfolioCtrl',
        controllerAs: '$ctrl'
    })
    .state('portfolio.patent', {
        url: '/:patentId',
        views:{
            "": {
                controller: 'caseOverviewCtrl',
                controllerAs: '$ctrl',
                templateUrl: 'app/templates/patent/case-overview.tpl.htm',
            },
            //FURTHER SIBLING VIEWS
       }
     })

In portfolio in the controller I make a request, await the promise and then display the data to the user in a table. If the user selects an item from the table, it displays further information in a child state portfolio.patent, passing an id value to $stateParams, which I then use to make the $http call to fetch more information.

If I refresh the page, the child state is displaying before the parent state, as the parent state $http request takes longer to resolve as there is a lot more data to fetch. I've tried to check from the child state the value of portfolioLoaded but it only checks it once.

Question

How do I check the parent state promise has resolved, before displaying the child state to the user?

I see using ng-show in the `portfolio.patent' view to check the controller whether the parent promise has been resolved.

PORTFOLIO CONTROLLER

var promise = patentsRestService.fetchAllPatents();
promise.then(
    function(response){
        var patents = response;
        $scope.portfolioLoaded = true;
    }
)

PORTFOLIO.PATENT CONTROLLER

function init() {
    if($scope.$parent.portfolioLoaded) {
        $scope.parentLoaded = true;
    }
}

PATENT VIEW

<div data-ng-show="$ctrl.portfolioLoaded" class="animate-show">
   //CONTENT
</div>

Solution

  • Save the promise in the parent controller:

    $scope.promise = patentsRestService.fetchAllPatents();
    $scope.promise.then(
        function(response){
            var patents = response;
            $scope.portfolioLoaded = true;
        }
    )
    

    Use the promise in the child controller:

    function init() {
        $scope.$parent.promise.then(function() {
            $scope.parentLoaded = true;
        });
    }
    

    This will properly delay the setting.