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?
@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.
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.
The "Application Module" can 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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With