Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting a primitive type in AngularJS

I'm learning my way around AngularJS at the moment. I've largely got to grips with the way Angular handles dependency injection, but there's a gap I can't find an answer for.

Say I have a service which retrieves data from the web, based on a user's query; it might look like this:

var webBasedServiceModule = angular.module('WebBasedService', []);

webBasedServiceModule
    .factory('webBasedService', function ($http) {
        var rootUrl = "http://example.com/myApi?query=";
        return {
            getData: function(query) {
                return $http.get(rootUrl + query)
                    .then(function(httpCallbackArg) {
                        return doSomething(httpCallbackArg);
                    });
            }
        }
    });

I'm injecting the $http service, so I can mock it for testing. However, I've got the root URL of my web service hard-coded in the class. Ideally, I'd like to decouple this URL from the service class, and inject it as a dependency. However, I don't see a way to inject a string or another primitive into an angular factory function. I would ideally like the code to look like this:

var webBasedServiceModule = angular.module('WebBasedService', []);

webBasedServiceModule
    .factory('webBasedService', function ($http, rootUrl) {
        return {
            getData: function(query) {
                return $http.get(rootUrl + query)
                    .then(function(httpCallbackArg) {
                        return doSomething(httpCallbackArg);
                    });
            }
        }
    });

One solution I can see is just to create a UrlProviderService and inject that service into the WebBasedService module, then call urlProvider.Url or similar. That seems a little smelly: it seems like overkill to create a whole new service just for one piece of configuration data. I can even imagine that I might create a service which is a string, like so:

var urlServiceModule = angular.module('UrlService', []);

urlServiceModule
    .factory('rootUrl', function () {
        return "http://example.com/myApi?query=";
    });

This seems like an abuse of the service concept though.

Does AngularJS offer a 'standard' solution to the problem of injecting primitives as configuration data? Or do I just use one of the solutions above?

like image 311
Peter Avatar asked Jul 29 '13 23:07

Peter


People also ask

What does @inject do in Angular?

@Inject() is a manual mechanism for letting Angular know that a parameter must be injected. Injecting ChatWidget component to make the component behave like a singleton service so that the component state remain same across the app.

How do I inject a module in AngularJS?

Injecting a value into an AngularJS controller function is done simply by adding a parameter with the same name as the value (the first parameter passed to the value() function when the value is defined). Here is an example: var myModule = angular. module("myModule", []); myModule.

Which components can be injected as a dependency in AngularJS?

The "Application Module" can be injected as a dependency in AngularJS.

Which components Cannot be injected as a dependency in AngularJS?

Note that you cannot inject "providers" into run blocks. The config method accepts a function, which can be injected with "providers" and "constants" as dependencies. Note that you cannot inject "services" or "values" into configuration.


1 Answers

You can use .constant() to inject in your configuration.

var app = angular.module("app", []);

app.constant("rootUrl", "http://www.example.com");

app.factory('webBasedService', function ($http, rootUrl) {
    return {
        rootUrl: rootUrl
    }
});

app.controller("MyCtrl", ["$scope", "webBasedService", function ($scope, webBasedService) {
    $scope.rootUrl = webBasedService.rootUrl;
}]);

Example on jsfiddle

like image 194
Mark Coleman Avatar answered Oct 07 '22 06:10

Mark Coleman