Last night at the AngularJS meetup, I talked with AJ and Joe Eames about how to make a reusable providers. They didn’t know exactly but I finally figured it out so I thought I’d share.
See this plunker demo.
Basically, I wanted to make a provider similar to ngResource that could simplify data resolution. I wanted to make it reusable so I put it into its own module.
It had to be a provider so that I could inject it into my main app’s .config()
function. Services and factories cannot be injected into .config()
. The
Angular docs have
a helpful table to explain that.
I needed the provider available in .config()
so I could define my routes there
and use the provider for the resolve objects.
So my provider needs to rely on $http
and $route
. The problem is that those
are not defined at the .config()
phase of a module. So I couldn’t define any
provider functions that rely on those.
That is where the concept of $get
comes in with providers. $get
is processed
by $injector.invoke()
which allows $get
to be a function with a dependency.
Usually you see an array like this:
this.$get = ['$http', '$route', function($http, $route) { ...
return this; // or any other object
}];
So in .config()
my provider can’t do anything with $http
or $route
, but it
can queue up tasks that will be handled by $http
and $route
later. In my
case when a route was fired.
So when I write a controller that relies on ApiProvider
I access it as Api
instead of ApiProvider
. And the controller will receive the object returned by
this.$get()
so the provider is guaranteed to have those dependencies by then.
That was probably hard to follow but hopefully that helps someone.