Add existing JS object to Angular app as a dependency - angularjs

I'm new to Angular and trying to figure out how to inject some external objects into Angular.
I have a JS script defining a global Payment object with some methods on it. I'd like to somehow import it (the Payment object) into an Angular service (from what I understood the service would be the place to that). How exactly does one go about that?
What I'd like to achieve in the end would be something like:
app.controller("myController", [PaymentService, function (payment) {....}]);

This would work :
app.factory('PaymentService',['$window', function($window){
return $window.Payment;
}]);
Using a factory is an occasion to add additional behavior, for example adding methods or checking that the global object is defined.

You can declare it either as a value:
angular.module('foo').value('PaymentService',window.Payment);
or as a constant:
angular.constant('foo').value('PaymentService',window.Payment);

Related

Angular js - Hide private variables from factories

Pls refer - http://jsfiddle.net/36qp9ekL/629/
I am using a factory method so that i can hide the implementation logic, private(pvt) variables and all the pros that factories are meant for.
If you run the code and see the console, I am able to view pvtvar1 and pvtvar2. How do I actually hide the pvt variables, implementation details.
app.controller("mycontroller", function($scope, myfactory) {
console.log(myfactory);
});
If you could tell the advantages of factories over services, would be helpful.
app.factory("myfactory", function() {
var pvtvar1= 3;
var pvtvar2 = 4;
return {
a:function(){
return pvtvar2 + pvtvar1;}
}
});
You are declaring the object and the function on the same scope of the variables. That's why they are shown. Here I declare the function on the object's scope. Take a look at this for more details http://toddmotto.com/mastering-the-module-pattern/
As you know, there are no privates in javascript. You are using closure to create inaccessible variables and functions. This is as good as you'l get. The console may show you (depending on the browser) properties that are defined via closure, but the important thing is, these properties aren't accessible in your code.
Advantages of a service over a factory? You can create an injectable service from a js object instead of a function so you can create services that inherit functionality. Not terribly useful since the injectable model is a replacement for inheritance in many ways but it's still an option.
I exclusively write services instead of factories but I'm using typescript in my projects (which has privates ;))

What is the difference between angular.Module.factory and angular.Module.service when creating a service?

I'm getting re-acquainted with angular after a long time away, and (so far) I've discovered two ways to create an angular service. The simplest being this:
var app = angular.Module("SomeApp", [])
.factory("SomeService", function ($log) {
$log.info("Yea beh beh! Dis hea is a service!")
});
This form of creating a service in angular is documented in angular.Module.factory. But, you can also see, that on the same page there is another way to create a service, using angular.Module.service.
Reading the two descriptions, I am unable to understand the differences other than .service needs you to explicitly use new to instantiate a service, whereas .factory implicitly does it for you. I might be wrong here, since I'm unable to understand because I have no clue what a $get property is. So, to wrap up:
What is a $get property?
What is the difference between .service and .factory?
Lastly, because this bugs me:
With all angular.Module.{service, factory, controller}, the second argument is a function. But, for instance, you have put in a list for the second argument in a controller, and name its dependencies. Then why is the type taken to be a function, rather than object? I mean you won't know from the documentation that you can declare dependencies in a list unless you've done a tutorial or something.
Both angular.Module.factory and angular.Module.service are proxies to angular.Module.provide. When you give a function to angular.Module.factory angular creates the respective service by invoking the function and using its return value as the service. On the other hand, when you give a function to angular.Module.service angular will treat it as an constructor and invoke it with the new keyword to create the service.
Thus creating a service with angular.Module.factory looks like this:
app.factory('MySimpleService', function () {
return {
aServiceProperty : 'a property containing a string'
};
});
And creating a similar service with angular.Module.service looks like this:
app.service('MyOtherSimpleService', function () {
this.aServiceProperty = 'a property containing a string';
});
The definition of the $get propery can be found here
Looks like this question has already been asked and answered. I am unable to comment, so I posted an answer.

Why angular.injector(), when we have angular.module('moduleName', [<Dependencies If any>]);

everybody, As you can see the title, i have to confirm my understanding, that
If we have :
angular.module('moduleName', [<Dependencies If any>]);
Then, do we really need this angular.injector, or is it just an another alternative.
If there is any other advantages of using the angular.injector, please let me know.
I have couple of other doubts.
we can use $filter in controller to get the particular filter and use its functions if any.
1. so how to use/call filters in directives.
2. how to call one controller function in another controller, is it possible?
Please Let me know the advantage of using angular.injector over angular.module('moduleName', [<Dependencies If any>]); And when it is good/needed to use it. not the implementaion of angular.injector
I needed it to get some services outside of the angular scope. For example my application is running on some legacy one. To change some parameters in the angular applicaion I needed to access an angular service from javascript outside of the angular. Then I used angular.injector to get the service.
injector = angular.element('#myangularDiv')).injector()
service = injector.get('theService')

'Stand Alone' Controllers VS modular controllers in angularJS

I am new to angularJS. I have been reading many code examples and I often see controllers defined as:
function MyController($scope) {
//code here
};
I however am using the method below to define my controller, as I wasn't aware there was any other way to do it.
angular.module("csApp.controllers", [])
.controller("main", function ($scope) {
//code here
};
How does the first method work? Is there some sort of naming convention I am missing here?
Are people using the first method simply adding these functions as global variables by placing them in in script files after angular loads?
How would you connect a global variable to a route if the controller is not registered with angularJS?
Thanks!
The AngularJS Dependency Injection framework can always find controller constructor function in global scope as they are global by nature. Even the ng-controller directive has this in its documentation
Name of a globally accessible constructor function or an expression
that on the current scope evaluates to a constructor function.
When using $routeProvider you can provide the route definition a Controller class or a quoted controller name which has been registered using the module api. These two are valid
route :{controller:MainCtrl,...}
route :{controller:'main',...}
The module based approach is preferable because it stops one from polluting the JS global namespace.
You just need to initialize your module, then you can declare your controllers with the two methods.
The first method make it easier and more readable when you have for instance 5 controllers, or if you want to split them in differents files. But they do the same job. All you need to do is keeping track your controller name.
function MainCtrl($scope) {
// do your stuff
}
<!-- Using the function name here -->
<ANY ng-controller="MainCtrl">
<!-- your HTML data -->
</ANY>
More info in the API Doc.

How to disable auto-injector (magic discovery of injector types) in angularjs?

Angularjs has this nice feature of auto discovery of the providers based on a function arguments.
For example, if I want to use $http in some function i would call it like that:
$inject.invoke(function ($http) {
});
Angularjs will "know" what are my dependencies. It will figure it out by reading my function's body and based on argument names it will know.
However there is a problem when you would like to minify your code. Minifier will change arguments names. That's why we should use this notation:
$inject.invoke(['$http', function ($http) {}]);
or this notation:
function Foo ($http) {}
Foo.$inject = ['$http'];
$inject.invoke(Foo);
We should always in the end minify our code. So we should avoid using this magic (first example) notation.
And now my problem:
I'm trying to minify my js code and angularjs cannot resolve a provider name.
I can't find a place where i haven't specified .$inject = [...]. Now it just says: "Unknown provider a" and i don't know what function is it referring to.
Is it possible to turn off angularjs auto discover (auto-injector) of providers? I would test and repair my code before minifying.
So, I'm wondering how to disable this "magic" angularjs deduction.
Since I always minify my code I want angularjs to yell at me when I will accidentally use this superheroic evil.
How to turn it off?
Just edit the source. Find 'function annotate', and replace the fn == 'function' block with something like this:
if (typeof fn == 'function') {
console.log("Bad magic injection in "+fn.toString().replace(STRIP_COMMENTS, ''));
}
update:
If anyone needs this because of trying to minify, maybe here is another possible solution
ngmin. It is an AngularJS application minifier project.
Not sure if this help.
According to Igor Minar,
You should make something like this
factory('Phone', function($resource){ ... }))
to
factory('Phone', ['$resource', function($resource){ ... })])
Here is the official doc from Dev guide.
$inject Annotation
To allow the minifers to rename the function parameters and still be
able to inject right services the function needs to be annotate with
the $inject property. The $inject property is an array of service
names to inject.
var MyController = function(renamed$scope, renamedGreeter) {
...
}
MyController.$inject = ['$scope', 'greeter'];
Care must be taken that the $inject annotation is kept in sync with
the actual arguments in the function declaration.
This method of annotation is useful for controller declarations since
it assigns the annotation information with the function
From 1.3.0-beta.6 onwards angularjs supports ng-strict-di option which can be used along with ng-app directive to disable auto-injection.
From Documentation
if this attribute is present on the app element, the injector will be
created in "strict-di" mode. This means that the application will fail
to invoke functions which do not use explicit function annotation (and
are thus unsuitable for minification), as described in the Dependency
Injection guide, and useful debugging info will assist in tracking
down the root of these bugs

Resources