Search code examples
angularjsgruntjstypescriptbowerrestangular

Can't resolve dependency for module function (restangular.IProvider)


I'm trying to setup restangular for a SPA project but I'm unable to resolve it as a dependency with grunt-tsng. I've installed it using bower (and tsd for typescript definitions from definitelyTyped).

grunt task configuration

tsng: {
        options: {
            extension: ".ng.ts"
        },
        dev: {
            files: [
                // TODO: Automate the generation of this config based on convention
                {
                    src: ["Client/app/**/*.ts", "!**/*.ng.ts"],
                    dest: "Client/app"
                }
            ]
        }
    },

Module app.ts

/// <reference path="../../typings/tsd.d.ts" />

module App {

    var dependencies = [
        "ui.router",
        "ui.bootstrap",
        "restangular"
        ...
    ];

    function configuration(
        $stateProvider: ng.ui.IStateProvider,
        $urlRouterProvider: ng.ui.IUrlRouterProvider,
        RestangularProvider: restangular.IProvider, <-- here it fails
        ...

ts.d.ts (reference file)

/// <reference path="restangular/restangular.d.ts" />

grunt error

Running "tsng:dev" (tsng) task
Warning: Error: Can't resolve dependency for module function App.config with name restangular.IProvider Use --force to continue.

Other dependencies, such as ui-router, ui-bootstrap etc. are working fine. What could be the cause of this? Are there any incompatibilities known with grunt-tsng?


Solution

  • Alright, I figured it out.

    When executing grunt-tsng, it scans all dependencies/modules etc. to automagically hook them into angular so you don't have to do it yourself. Here two simple rules apply: Dependencies to inject that are your own (e.g. where you have typescript inplementation code present, such as classes in your modules) can be defined simply with their name. E.g.:

    constructor(service: MyModule.IMyService) {}
    

    External dependencies, e.g. from angular itself are declared with the '$' notation. grunt-tsng will assume their dependencies itself are resolved at runtime and thus just hooks them up with their name:

    constructor($routeProvider: ng.IRouteService) {}
    

    But now services in restangular aren't named '$restangular', but just 'restangular'. This leads to the following:

    • When declaring it as 'restangular', grunt-tsng will look for implementations in your modules, doesn't find any and fails
    • When declaring it as '$restangular', angular will look for providers called '$restangular', doesn't find any and fails

    Conclusion:

    This is retarded.