Introduction

Existing printing projects such as, ZPL or EPL accomplish most of their processing in the Browser. These systems run in conjunction with different APIs and Windows Services to handle the printing jobs on specialized printers. Its main goal, is to ensure optimal performance and to maximize the processing of print requests.

The most operative approach is to use AngularJS. It has many nifty features that provide an agile and effortless development.

How Angular.JS Works

AngularJS comes with a built-in dependency injection mechanism. AngularJS allows for the division of different components by injecting them into each other. AngularJS has the scope to each DOM element, and when the scope is defined it uses a dependency injection (Design pattern) to process. (See Fig. 1.1)

Understanding-AJS-001

Fig 1.1

Core Objects

The following are the core type of objects and components that have been infused via AngularJS.

  • Value
  • Factory
  • Service
  • Provider
  • Constant

Value

A value in AngularJS is a simple object. It can be a number, string or JavaScript object. Values are typically used as a configuration, which are injected into factories, services or controllers. A value must belong to an AngularJS module. Here are three examples that add values to an AngularJS module:

var myModule = angular.module("myModule", []);
myModule.value("numberValue", 999);
myModule.controller("MyController", function($scope, numberValue) {
   console.log(numberValue);
});

 

*Notice how the second parameter of the controller function has the same name as the value.

Factory

A factory is a function that creates values. When a service, controller, etc. needs a value injected from a factory, the factory creates the value on demand. Once created, the value is reused for all services, controllers, etc. that require injection this makes a factory differ from a value; because it can use a factory function to create the object it returns. Values can also be injected into a factory for use, when creating the object. This cannot be done with the value by itself.

Here is an example that defines a factory on a module, and a controller with an injected value:

var myModule = angular.module("myModule", []);
myModule.factory("myFactory", function() {
return "a value";
});
myModule.controller("MyController", function($scope, myFactory) {
console.log(myFactory);
});

This is very similar to defining and injecting a value object. Keep in mind that it is not the factory function that is injected, but the value produced by the factory function.

Below is an example of how you can inject the values using the Factory Method:

var myModule = angular.module("myModule", []);
myModule.value("numberValue", 999);
myModule.factory("myFactory", function(numberValue) {
return "a value: " + numberValue;
});

 

Service

A service in AngularJS is a single JavaScript object which contains a set of functions. The functions contain whatever logic is necessary for the service to carry out its work. AngularJS services are created using the service () function on a module.

Here is an example of how AngularJS services are created:

function MyService() {
this.doIt = function() {
console.log("done");
}
}
var myModule = angular.module("myModule", []);
myModule.service("myService", MyService);
myModule.controller("MyController", function($scope, myService) {
myService.doIt();
});

Injecting Values to Service

var myModule = angular.module("myModule", []);
myModule.value ("myValue" , "12345");
function MyService(myValue) {
this.doIt = function() {
console.log("done: " + myValue;
}
}
myModule.service("myService", MyService);

 

Providers

Providers in AngularJS are the most flexible form of factory created. A provider is registered with a module, similar to a service or factory, only the provider () function is used instead.

Here is an AngularJS provider example:

var myModule = angular.module("myModule", []);
myModule.provider("mySecondService", function() {
var provider = {};
provider.$get = function() {
var service = {};
service.doService = function() {
console.log("mySecondService: Service Done!");
}
return service;
}
return provider;
});

 

The provider () function takes 2 parameters. The first parameter is the name of the service or object which the provider creates. In this case the name is “mySecondService”. The second parameter is the function which creates the provider.

*Note: The provider itself is a factory, so at this time no actual service or object is created from the provider. Only the function creating the provider is defined.

The function creating the provider is a JavaScript object.The JavaScript provider object contains a single $get() function (the factory function of the provider). In other words, the $get() function creates whatever the provider creates (service, value etc.). In the example above, the provider creates a service object which contains a single service function (standard JavaScript function) called doService().

In order to get the product of a provider injected into a controller, specify a dependency on the provider, similar to a service. Whatever is injected into the controller is the product created by the provider, but not the provider itself.

Here is an AngularJS provider injection example:

myModule.controller("MyController", function($scope, mySecondService) {   $scope.whenButtonClicked = function() {
       mySecondService.doIt();
   }
});

 

*In the above example, the object created by the provider’s $get() function is infused into the parameter.

Configuring a Provider

It is possible to configure a provider further by reaching out to its function during the configuration phase of a module.

Here is an example of how to configure a provider by calling to its function:

var myModule = angular.module("myModule", []);
myModule.provider("mySecondService", function() {
   var provider = {};
   var config = { configParam : "default" };
   provider.doConfig = function(configParam) {
       config.configParam = configParam;
   }
   provider.$get = function() {
       var service = {};
       service.doService = function() {
          console.log("mySecondService: " + config.configParam);
       }
       return service;
   }
   return provider;
});
myModule.config( function( mySecondServiceProvider ) {
   mySecondServiceProvider.doConfig("new config param");
});
myModule.controller("MyController", function($scope, mySecondService) {   $scope.whenButtonClicked = function() {
       mySecondService.doIt();
   }
});

 

*Notice how the provider object now has an extra function called doConfig(). This function can be used to set a configuration parameter on the provider.

Notice, the call to the myModule.config() function. The config function takes a function as a parameter, this function can than configure the module. The function passed to config() takes a single parameter named “mySecondServiceProvider”. This is the same name as the provider it is registered with as well as, the provider as the suffix. The suffix tells AngularJS to inject the provider itself, and not the object created by the provider. Inside the function next to the config() function the mySecondServiceProvider.doConfig() function is called, this sets the config parameter on the provider.

The controller defined later in the example just depends on the object created by the provider (not the provider itself). It is defined by taking a parameter named “mySecondService” (the name of the provider registered) The service is used from inside the $scope.whenButtonClicked() function.

Constants

In the section “providers”, a provider was configured through a function. In this particular example values cannot be infused into the function, instead you must inject constants. Constants in AngularJS are defined using the module constant’s () function.

Here is an AngularJS constant example:

myModule.constant("configValue", "constant config value");

 

This constant can now be injected into the module.config() function like this:

myservices.config( function( mySecondServiceProvider, configValue ) {
   mySecondServiceProvider.doConfig(configValue);
});

In the above example, the parameter configValue matches the name of the constant which is also configValue. The value of the constant is then injected into this parameter. The constant value is then passed as a parameter to the doConfig() function on the mySecondServiceProvider provider.

Dependencies between Modules

Values, factories and services can be added to an AngularJS module. It is possible for one module to use the values, factories and services of another module. In order to do so, a module needs to declare a dependency on the module which contains the values, along with the factories and services it wants to use.

Below is an example of how the modules can collaborate:

var myUtilModule = angular.module("myUtilModule", []);
myUtilModule.value ("myValue" , "12345");
var myOtherModule = angular.module("myOtherModule", ['myUtilModule']);
myOtherModule.controller("MyController", function($scope, myValue) {
});

Notice how the second module (myOtherModule) lists the name of the first module (myUtilModule) in the second parameter (inside the array) next to the angular.module() function. This tells AngularJS that all values, factories and services defined inside the myUtilModule should be available inside themyOtherModule module too. In other words, myOtherModule depends on myUtilModule.

The MyController controller function can now declare the parameter named “myValue”. This value is provided from the value registered on the myUtilModule module.

Minification Safe Dependency Injection in AngularJS

The JavaScript minifier replaces the names of local variables and parameters with shorter names once it is minified. However, AngularJS uses the parameter names of controller functions, factories, services and providers to decide what to inject into their factory functions. If the names are changed, AngularJS cannot inject the correct objects.

To keep the AngularJS code minification safe, the names of the objects must be provided to inject as string, the strings are then conjoined with the function.

Here is an AngularJS minification safe dependency injection example:

var myapp = angular.module("myapp", ['myservices']);
myapp.controller("AController", ['$scope', function(p1) {
   p1.myvar = "the value";
}]);

The above example injects the $scope object into the p1 parameter of the controller function. Notice that the controller function is registered. Instead of passing the controller function directly to the angular controller function, an array is passed. This array contains the name of the value injected into the controller function, as well as the controller function itself. The controller function is always the last value in this array. If more than one value needs to be injected, the value names are listed in the beginning of the array and in the sequence.

Below is a minification safe multi value example.

var myapp = angular.module("myapp", ['myservices']);
myapp.controller("AController", ['$scope', '$http', function(p1, p2) {
p1.myvar = "the value";
p2.get("/myservice.json");
}]);

The above example injects the $scope object into the p1 parameter, and the $http service into the p2 parameter of the controller function. Now it no longer matters what the parameter names of the controller function are. AngularJS will use the strings in the beginning of the array to determine what to inject into the controller function. The same mechanism can be used for factories, services and providers to provide a minification safe dependency injection.

Here is a minification safe factory, service and provider example:

var myutil = angular.module("myutil", []);
myutil.value("safeValue", "a safe value");
myutil.factory("safeFactory", ['safeValue', function(p1) {
return { value : p1 };
}]);
function MySafeService(p1){
this.doIt = function() {
return "MySafeService.doIt() called: " + p1.value;
}
}
myutil.service("safeService", ['safeFactory', MySafeService]);
myutil.provider("safeService2", function() {
var provider = {};
provider.$get = ['safeService', function(p1) {
var service = {};
service.doService = function() {
console.log("safeService from provider: " + p1.doIt());
}
return service;
}];
return provider;
});
myapp.controller("AController", ['$scope', 'safeService2', function(p1, p2) {
p1.myvar = "the value";
p2.doService();
}]);

Closely observe the declaration of the provider function and recognize the dependencies that are not specified on the provider factory function. This is because the $get() function of the provider is returned from inside the provider’s factory function. An array with names of dependencies and the function implementation is used instead of just a $get()function. Specifying dependencies usually works the same for providers, factories, services and controller functions.