I’m still a learner at Angular (aren’t we all?), but overall I’ve had a pleasant experience with the framework. I feel like it’s easier to compose solutions with the framework than without it. I wouldn’t consider myself a cheerleader for the framework, but when I ran across this blog post, I felt a little bit annoyed. Clearly, the tone of the article is intended to be a bit harsh in a humorous way. That didn’t stop me from feeling a bit slighted by the title. Are Angular developers really ruining the experience of the language?
Rob’s tirade comes to a close when he brings up the following quote from this StackOverflow answer:
But, why CarProviderProvider instead of CarProvider
The code in question is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
app.service('CarService', function () { this.dealer = "Bad"; this.numCylinder = 4; }); app.factory('CarFactory', function () { return function (numCylinder) { this.dealer = "Bad"; this.numCylinder = numCylinder }; }); app.provider('CarProvider', function () { this.dealerName = 'Bad'; this.$get = function () { return function (numCylinder) { this.numCylinder = numCylinder; this.dealer = this.dealerName; } }; this.setDealerName = function (str) { this.dealerName = str; } }); app.config(function (CarProviderProvider) { CarProviderProvider.setDealerName('Good'); }); |
On the surface, this is silly, right? Why should I have to repeat the word provider like that? Actually, you don’t. The reason CarProviderProvider
exists is because the example is showing the difference between defining a service and a provider. When creating an actual service using the app.provider
function, you would just use the name of the service. Here’s what I mean:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
app.provider('foo', function() { var bar = 'Bar'; this.$get = function FooFactory() { return function() { // Earth-shattering service functionality here }; }; this.bar = function(barValue) { bar = barValue; }; }); |
You’ll notice that I gave a name to the function stored in the $get
property. This can help tremendously when debugging services. Also, I made the configurable value private while exposing a setter. This is because providers should only be configured once per module, and that configuration happens before any services are instantiated using app.config
. The above definition would allow the use of a foo
service without configuration, or by specifying configuration like so:
1 2 3 4 5 |
app.config(function(fooProvider) { fooProvider.bar('Baz'); }); |
The Angular framework sometimes appears to be performing magic tricks and creating objects from out of nowhere, but as AJ O’Neal once demonstrated, it’s really just string manipulation coupled with a brilliant application of Javascript’s bind
and apply
functions. The important thing is that, by passing a constructor and a name to app.provider
, you are defining a service provider that can be configured before the service is instantiated. Does every service need to be configurable? No, just like every app doesn’t need an MVC framework. Technically, no one needs a framework, but using one doesn’t automatically ruin the joy of development for everyone else, does it?