UI Router resolve not working with component-based states

214 views Asked by At

Background:
On an app I am working on, we have a component that is being used in two places. In one place it's being called from the Material Design bottomSheet system. In another, we are using the component directly via the ui-router state system.

Here's the setup that's causing trouble. I've already got an angular.module statement that has all the proper package dependencies set up - I've been working on this app for months with my team, the problem is specifically the code below, which is what I've just added.

routes.ts

namespace Main {
    RouteConfig.$inject = ['$stateProvider'];

    function RouteConfig($stateProvider) {
        $stateProvider
            .state('main.myAwesomeFeature', {
                url: '^/myawesomefeature',
                component: 'awesomefeature',
                resolve: {
                    awesomeDefaults: () => new Controllers.AwesomeDefaults(1, 2, 3)
                }
            });

        // Other routing minutiae, unimportant to the question
    }

    angular.module('app').config(RouteConfig)
}

awesomefeature.ts

namespace Controllers {
    export class AwesomeDefaults {
        public constructor(
            number1: number,
            number2: number,
            number3: number
        ) {
        }
    }

    export class AwesomeFeatureCtrl {
        public static $inject: string[] = [
            'awesomeDefaults'
        ];
        public controller(
            public awesomeDefaults: AwesomeDefaults
        ) {               
        }

        // ...Other methods and irrelevant stuff...
    }

    angular
        .module('app')
        .controller('awesomeFeatureCtrl', AwesomeFeatureCtrl);
}

namespace Components {
    export var awesomeFeatureCmpt: ng.IComponentOptions = {
        bindings: {},
        controller: 'awesomeFeatureCtrl',
        controllerAs: '$ctrl',
        templateUrl: '(Irrelevant, as is the HTML)'
    };

    angular
        .module('app')
        .component('awesomefeature', awesomeFeatureCmpt);
}

Problem: Whenever I try to navigate directly to the 'Awesome Feature', not only does my HTML not render, I receive the following console error:

angular.js:14525 Error: [$injector:unpr] Unknown provider: awesomeDefaultsProvider <- awesomeDefaults <- awesomeFeatureCtrl  
http://errors.angularjs.org/1.6.4/$injector/unpr?p0=awesomeDefaultsProvider%20%3C-%20awesomeDefaults%20%3C-%20awesomeFeatureCtrl  
    at angular.js:66  
    at angular.js:4789  
    at Object.getService [as get] (angular.js:4944)  
    at angular.js:4794  
    at getService (angular.js:4944)  
    at injectionArgs (angular.js:4969)  
    at Object.invoke (angular.js:4995)  
    at $controllerInit (angular.js:10866)  
    at nodeLinkFn (angular.js:9746)  
    at angular.js:10154  

It appears that for whatever reason, $stateProvider.state({resolve}) isn't properly resolving my awesomeDefaults and injecting the value into the awesomeFeatureCtrl.

Question:
Why isn't resolve working as I recall that it should?

To my understanding, the resolve object takes each named index on it, runs whatever function is on it, and then resolves it into the controller of the thing in the route, as per the UI Router Documentation. It's obvious I'm mis-remembering or mis-understanding something.

1

There are 1 answers

0
tcrite On

After looking at your error more closely, I’ve run into this issue before. Try changing this

resolve: {
                awesomeDefaults: () => new Controllers.AwesomeDefaults(1, 2, 3)
            }

To this

resolve: {
                awesomeDefaults: /** ngInject */ () => new Controllers.AwesomeDefaults(1, 2, 3)
            }

To properly inject awesomeDefaults.