UI-Router will not resolve $http call

2019-06-14 15:52发布

问题:

I have a api that i want to resolve name for "bubble". This i would like to inject into controller - but problem is that i have tried different approaches and all just say...undefined and some injection problems... :(

Code:

.state('bubbles', {
    abstract: false,
    url: "/bubbles/:bubbleId/feed",
    controller: 'BubblesController',
    data: {
        authorizedRoles: [USER_ROLES.editor]
    },
    resolve: {
        resolvedBubbleName: function ($http, $stateParams) {
            var url = 'https://XXXXXXX.net/api/Bubble/11111111-1111-1111-1111-111111111111';
            return $http.get(url)
            .then(function (response) {
                console.log('response ' + response);
                return response;
            });
        },
        views: {
            'navigation': {
                templateUrl: "/raqt/shared/partials/navigation.html"
            },
            'main': {
                templateUrl: "/raqt/bubbles/partials/bubbles.html"
                //controller: function ($scope, resolvedBubbleName) {
                //    $scope.resolvedBubbleName = resolvedBubbleName; 
                //  // resolvedBubbleName is always undefined, i.e.,
                //  //  UI router is not injecting it
                //}

            }
        },
    }

})

In my controller i tried different approaches and this that i think should work... gives error injection...

BubblesController.$inject = ['$stateParams', '$state', '$log', '$timeout', '$interval', '$scope', 'BubblesService', 'CONFIG', '$http', 'resolvedBubbleName'];

function BubblesController($stateParams, $state, $log, $timeout, $interval, $scope, BubblesService, CONFIG, $http, resolvedBubbleName) {
    $scope.title = 'bubbles-controller';
    alert(resolvedBubbleName);
    $scope.bubbleId = $state.params.bubbleId;

Error from page

Error: [$injector:unpr] Unknown provider: resolvedBubbleNameProvider <- resolvedBubbleName <- BubblesController
http://errors.angularjs.org/1.3.15/$injector/unpr?p0=resolvedBubbleNameProvider%20%3C-%20resolvedBubbleName%20%3C-%20BubblesController
    at REGEX_STRING_REGEXP (http://localhost:3604/js/lib/angular/angular.js:63:12)
    at http://localhost:3604/js/lib/angular/angular.js:4015:19
    at Object.getService [as get] (http://localhost:3604/js/lib/angular/angular.js:4162:39)
    at http://localhost:3604/js/lib/angular/angular.js:4020:45
    at getService (http://localhost:3604/js/lib/angular/angular.js:4162:39)
    at Object.invoke (http://localhost:3604/js/lib/angular/angular.js:4194:13)
    at $get.extend.instance (http://localhost:3604/js/lib/angular/angular.js:8493:21)
    at http://localhost:3604/js/lib/angular/angular.js:7739:13
    at forEach (http://localhost:3604/js/lib/angular/angular.js:331:20)
    at nodeLinkFn (http://localhost:3604/js/lib/angular/angular.js:7738:11) <div ui-view="main" class="ng-scope">

I can see that $http call is having data and i know controller works well otherwise - but this resolve driving me mad.. :(

I will be off for couple of hours - but i WILL ge back to this if you see some problems in my code i will ge back and answer!... :)

回答1:

I would say, that you've wrongly nested views : {} into the resolve : {}. There is a working plunker

I just moved your definitions into correct positions and it is working

.state('bubbles', {
    abstract: false,
    url: "/bubbles/:bubbleId/feed",
    //controller: 'BubblesController',
    data: {
      authorizedRoles: [{}], //USER_ROLES.editor]
    },
    resolve: {
      resolvedBubbleName: ['$http', '$stateParams',
        function($http, $stateParams) {
          //var url = 'https://XXXXXXX.net/api/Bubble/11111111-1111-1...';
          var url = 'someData.json'
          return $http.get(url)
            .then(function(response) {
              console.log('response ' + response);
              return response.data;
            });
        }
      ],
    },
    views: {
      'navigation': {
        templateUrl: "raqt/shared/partials/navigation.html",
        controller: 'BubblesController',
      },
      'main': {
        templateUrl: "raqt/bubbles/partials/bubbles.html",
        controller: ['$scope', 'resolvedBubbleName',
          function($scope, resolvedBubbleName) {
            $scope.resolvedBubbleName = resolvedBubbleName; 
          }
        ]
      }
    },
})

Also, one very important note:

controller belongs to view - not to state

You can read more here:

  • Are there different ways of declaring the controller associated with an Angular UI Router state

Check the working example here

EXTEND

In case, that we adjusted all the code as above and we are provided with this error:

Error: [$injector:unpr] Unknown provider: resolvedBubbleNameProvider <- resolvedBubbleName <- BubblesController

We are most likely in one of these scenarios:

  • we have elsewhere in our state hierarchy reused the "BubblesController", while not having resolve : { 'resolvedBubbleName': ... } in place
  • we declared somewhere ng-controller="BubblesController" - which is not managed by UI-Router. And it does not have access to so called locals (containing resolved values)

so, be sure where is the controller defined - all will start working then...