0

I would like to call my service from within app.config.

When searching for this, I found this question with a solution that i tried to follow (not the accepted answer, but the solution below with the title "Set up your service as a custom AngularJS Provider")

However with that solution and with the suggested alternative as well i run into problems when i am trying to call the service from within my app.config (The service does not seem to be called at all). I am new to angular and javascript and don't really know how to debug this properly (i am using firebug). I hope you can help me with some pointers and possibly a solution.

Current Code (trying to implement the "possible alternative" from the linked question:

angular.module('myApp', [
  'ngRoute',
])
.config(['$routeProvider', '$locationProvider', '$provide', function($routeProvider, $locationProvider, $provide) {

$provide.service('RoutingService',function($routeParams){
    var name = $routeParams.name;
    if (name == '') {name = 'testfile'}

    var routeDef = {};
    routeDef.templateUrl = 'pages/' + name + '/' + name + '.html';
    routeDef.controller = name + 'Ctrl';
    return routeDef;
})

//Here i would like to get a hold of the returned routeDef object defined above.
$routeProvider.when('/name:', {
                        templateUrl: RoutingService.templateUrl, 
                        controller: RoutingService.controller
                    });

My previous attempt was to declare the Service like this via a provider:

var ServiceModule = angular.module('RoutingServiceModule', []);

ServiceModule.provider('routingService', function routingServiceProvider(){
      this.$get = [function RoutingServiceFactory(){

         return new RoutingService(); 
      }]
});

function RoutingService(){
    this.getUrlAndControllerFromRouteParams = function($routeParams){
        var name = $routeParams.name;

        var routeDef = {};
        routeDef.templateUrl = 'pages/' + name + '/' + name + '.html';
        routeDef.controller = name + 'Ctrl';
        return routeDef;
    }
}

and tried to call it like i would usually call a service in a controller (after adding the RoutingServiceModel to the dependencies of myAppof course). In both cases the templateUrl and controller are not set when i navigate to my views, so I guess i am missing some dependencies, or am not calling the service correctly.

Any ideas?

Community
  • 1
  • 1
H W
  • 2,556
  • 3
  • 21
  • 45
  • The answer here: http://stackoverflow.com/questions/16828287/what-things-can-be-injected-into-others-in-angular-js answered my question in great detail. In theory I can use a provider during the `config` phase of my application, but i can not access any service instances (like i tried with `$routeParams`) until the `run` phase. – H W Jul 23 '15 at 14:24

2 Answers2

0

during the config phase, only providers can be injected (with the exception of the services in the AUTO module--$provide and $injector).

Please check this working demo: http://jsfiddle.net/nxbL66p2/

angular.module('Joy',[])
.config(function($provide) {
  $provide.provider('greeting', function() {
    this.$get = function() {
      return function(name) {
        alert("Hello, " + name);
      };
    };
  });
})
.controller('MyCtrl', ['$scope', 'greeting', function ($scope, greeting) {
    $scope.greet = function () {
        greeting('Joy');
    };
}]);

Simple HTML:

<div ng-app="Joy">
    <div ng-controller="MyCtrl">
        <div ng-click="greet()">Click to greet.</div>
    </div>
</div>

Reference: https://github.com/angular/angular.js/wiki/Understanding-Dependency-Injection

Joy
  • 9,430
  • 11
  • 44
  • 95
-1

Angular's terminology is a bit of a mess, because 'service' and 'provider' may designate different things, depending on the context. According to the statement in the manual,

An Angular service is a singleton object created by a service factory. These service factories are functions which, in turn, are created by a service provider. The service providers are constructor functions. When instantiated they must contain a property called $get, which holds the service factory function.

You can't inject services in config (except constant), only service providers, and your RoutingService is inapplicable there.

Technically, you can get a service there with

RoutingServiceProvider.$get();

But it will make a separate instance (rather than singleton object), and the usage of $routeParams makes no sense at the moment when it is being called in config.

You can have templateUrl as function (see the manual), while dynamic controller names aren't suitable for route configuration, define them within templates with ng-controller instead.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • 1
    Technically I am trying to call a provider from within `config` which should be possible, right? Letting the provider provide a service should be possible as well from my understanding. I don't quite understand why the combination is inapplicable here - could you please explain this further? – H W Jul 23 '15 at 13:01
  • Taken from https://docs.angularjs.org/guide/services: `You can also register services via the $provide service inside of a module's config function:`. This is what i am trying to do with my RoutingService. Did I missunderstand "register" in this context? I assumed I can use the service immediately after it has been registered, – H W Jul 23 '15 at 13:14
  • Yes, you misunderstood it, `angular.provider('RoutingService', ...` and `$provide.provider('RoutingService', ...` is mostly the same thing (the latter is less universal because there will be problems with injecting RoutingServiceProvider into other `config` blocks). Angular makes singletons from service providers after all `config` blocks are done, and the purpose of `config` is to configure the providers before the services are instantiated. `$routeProvider` isn't an exception, it expects some *static* configuration before `$route` service will be instantiated. – Estus Flask Jul 23 '15 at 14:00