Provider

The provider is like a service that generates a factory. We can also create service as a provider. if that makes sense. During initialization, you can configure a provider to act a certain way after the application has loaded. The $http service is really a provider, and you can configure its defaults during initialization if you wish.

A provider returns nothing, but defines this.$get(); a function to return a factory-like object. When you define provider Test, you’re really defining TestProvider in config() ; the thing returned from this.$get is really Foo in a controller.

When should we use the provider?
1. We can use a provider to configure or set some value to configuration through config()
2. We can use our provider to a controller

The angular.module() has a function config(), which lets us configure a module, we can use a provider to set/initialize some value to config() method. We can use a provider to set parts of the service before the service can be consumed. Where config() is prototype method and is executed only one time in the application lifecycle. We can use a provider to set API configuration. Once the application is load, configuration get executed and whatever the data we configure in this config() function is shared inside our application.

The $route service is a good example of it. We use the underlying $routeProvider to configure the routes before they can be used in the app. We can use a provider to give the end user an option to set some default value, the default value can be used by other methods too.

The provider can be implemented by $get in a controller and any other in config. Whatever implement we have defined in $get of the provider can only be accessed by a controller and those implementations which are outside $get can be accessed by the controller.

Note: Referencing of a provider in controller and config have differed. In a controller, we can use provider reference as provider name in a controller. When using provider inside the config() method we have to use provider reference as providerName+Provider that is serviceProvider in our example below. 

Note: We can’t use a function of the provider which is defined outside $get the implementation of the provider inside our controller. This means whatever function that is defined inside the $get of the provider can access inside our controller by using provider reference. Eg // service.setValue(a); we can use this service method in our controller.

<html ng-app="myApp">
<html>
<script src="js/angular.min.js"></script>
<body ng-controller="myCtrl">
<div >
  Enter a Number <input type="number" ng-model="num"/><br/><br/>
  <button ng-click="getSquare(num)">Get square </button> | <button ng-click="getFactorial(num)">Get Factorial </button><br/><br/>
  Result : {{ result}}
</div>

<script>
  var app = angular.module("myApp", [])
  .provider("service", function() {

    var apiKey = '';
    this.setApiKey = function(value){
      apiKey = value;
    };

    this.$get = function(){
      var obj = {};
      obj.square = function(a){
        return a * a;
      };
      obj.factorial = function(a){
        var result = 1;
        for( var i = a; i > 0; i --){
          result *= i;
        }
        return result;
      };
      return obj;
    };
  })
  .config(function(serviceProvider){
     serviceProvider.setApiKey(35445);
  })
  .controller("myCtrl", function($scope, service){
      $scope.a = 0;
      $scope.result = 0;

      $scope.getSquare = function(a) {
      //  service.setValue(a);
        $scope.result = service.square(a);
      };

      $scope.getFactorial = function(a){
        $scope.result = service.factorial(a);
      };
  });
</script>
</body>
</html>