In this lesson, we discuss how and when to use factory providers, to enable dependencies that shouldn’t be available to Angular’s DI.
[00:00] Angular's dependency injection system uses type information to find out what to inject. In our list component, we have a data service dependency of type data service, and the type annotation that is attached to this constructive parameter is then used as a token in the provider configuration so Angular knows how to create the requested dependency.
[00:20] Sometimes, however, we have dependencies of a type that we can't or do not want to make available via DI. One example is this lock debugger class. It has a debug method that takes a message and simply prints it out in the console, but only if lock debugging is enabled.
[00:37] As we can see here, the debugger can be configured at creation time using the enable constructor parameter. We obviously have to inject a value for the enable parameter, and the type annotation clearly says that it's a boolean value, so it's either true or false.
[00:54] If we go back to our list component, add a provider for lock debugger, ask for an instance, and use it in our component, we see that Angular complains that it can't resolve all parameters for lock debugger dependency.
[01:21] When this error occurs, this usually means that we're requesting a dependency with a type that Angular doesn't know about. In other words, there is a provider missing for the requested type or token. In this case, we're asking for a dependency of type boolean in the lock debugger class, and we obviously don't have a provider configured for that type.
[01:43] We could try to add a provider for that type by doing provide boolean use value true, where its use value is the thing that's injected. However, this will not work, because boolean is not a custom-created type in this file, and it can only be used to add static type information to things like variables and parameters, as we do in our lock debugger.
[02:05] Even if that worked, with this provider, we would always inject a value true whenever we asked for a dependency of type boolean, which is probably not what we want, either.
[02:13] To handle such cases, we can tell Angular to specifically call a factory function to create the dependency. Inside that factory function, we are able to simply pass a boolean value to the lock debugger constructor.
[02:28] Let's go ahead and remove the provide for boolean and change the provider for lock debugger to provide lock debugger use factory. This is where we define the factory function, which will be called by Angular when we ask for an instance of type lock debugger.
[02:45] We create a function in which we return new lock debugger, and here we pass the boolean value, which is now true. We save the file and can see getting items is locked.
[02:59] To demonstrate that this really works, we change true to false, save the file, and once the browser is reloaded, we see that nothing is locked anymore.
[03:14] To recap, use factory gets a function which returns the dependency instance we want to inject later on. Inside that function, we can manually pass objects to a dependencies constructor without making these objects automatically available via DI.