I'm new to AngularJS. Sometimes I see:
angular.module(...)....
Sometimes
var app = angular.module(...)...
Sometimes the latter is wrapped in an IIFE.
When is it appropriate to use either one of the first 2? What real difference do they make?
Most style guides regarding angular recommends the first variant since you never really need to define a variable to reference the module.
You can access a module with angular.module('moduleName') like so:
angular
.module('app')
.controller('SomeController' , SomeController);
function SomeController() { }
I recommend this style guide by John Papa
1st Approach : with
var app = angular.module(...)...
you are saving a reference to the returned module instance and reuse it to register multiple service/configs/providers etc
so you will call methods on this like
app.config();
app.controller();
etc
2nd Approach : with this
angular.module(...)
you are chaining methods with dot in between them because angular.module(...) , contollers, providers returns module instance that can be chained
like
angular.module("sm",[]).config(function(){}).controller()... so on
Comparison/drawbacks/Advantages :
With first approach drawback is that we declare an "app" intermediate variable that could end up in global namespace if we dont use IIFE
(function() {
var app = angular.module(...)...
} )()
So we can use angular.module("...") with each controller/factory etc but that could be much of the repetition
luckily, we can use the second approcach to chain,because angular.module(...) , contollers, providers returns module instance
There is no difference but style you write your project.
Consider following example that demonstrate both cases you mentioned:
angular.module(...)
angular.module('myApp.', [])
.value('version', '0.1')
.service('apiFrontendService', ['$http', function($http) { /* */ }
.factory('localFactory', ['$http', function($http) { /* */ }
.controller('MyController', ['$http', function($http) { /* */ }
and so on. Here we chain our services one after another.
var app = angular.module(...)...
var app = angular.module('myApp.', []);
app.value('version', '0.1');
app.service('apiFrontendService', ['$http', function($http) { /* */ };
app.factory('localFactory', ['$http', function($http) { /* */ };
app.controller('MyController', ['$http', function($http) { /* */ };
Here you define once app and you can use it over all your project
Latter is used to define a global variable to store application's main Angular module. So, code can be splitted into files.
// app.js
var app = angular.module('testApp');
// aController.js
app.controller('aController', ...);
// bController.js
app.controller('bController', ...);
// someService.js
app.service('seriousService', ...);
Related
I am trying to inject a few helpers (lodash and a few of my own) in Angular controllers so I have:
angular.module('app').factory("_", Lodash);
Lodash.$inject = ['$window'];
function Lodash($window) {
if ($window._)
return $window._;
}
angular.module('app').factory("_", Helper);
Helper.$inject = ['$window'];
function Helper($window) {
return {
test: function () {
return "test";
}
}
}
So I would like all helpers to be accessible under _ and I would define them in a few JS files ... Can this be done?
With my code only one of them work: lodash methods or test().
For services that don't require dependencies ($window isn't crucial here because it serves for no purpose and can be replaced with window or _ global) config block is a good place to define them, because constant services are already available there.
app.config(function ($injector, $provide) {
var lodash = $injector.has('_') ? $injector.get('_') : {};
angular.extend(lodash, window._);
$provide.constant('_', lodash);
});
app.config(function ($injector, $provide) {
var lodash = $injector.has('_') ? $injector.get('_') : {};
angular.extend(lodash, {
test: ...
});
$provide.constant('_', lodash);
});
When the service is defined this way, its value can be extended several times, the order of config blocks doesn't matter.
Alternatively, service value can be changed with decorator, in order to do that the service should be already defined.
You can not redeclare a factory. As you already noticed, this will overwrite the previous.
You could prepare the helper in separate files and register them in one factory call elsewhere in your app.
how to inject a $rootScope into the factory definition for the following code (so the file can be minified):
(function() {
var signalRService = function($rootScope) {
// ...
};
var app = angular.module("App");
app.factory("signalRService", signalRService);
}());
The way to go about this is by supplying service definition as an array:
var signalRService = ['$rootScope', function($rootScope) {
// ...
}];
Argument will be minifed, but the injector will be based off the string in the array.
That said I'd suggest to revise whether this is really the way to go, as generally speaking relying on $rootScope is inadvisable, and so is using any kind of scopes directly in services/factories.
I have a directive which is associated with one controller and the functions in my controller defined as
MyFormController.prototype.addNewRow = function addNewRow() {
//Adding row code
};
I want to call this method from another controller, possible ways?
I ve user the service and moved the code into that service which is shared across the controllers, however the service code does the DOM manipulation, and then i guess the next question would be that can we use $compile in a service test case
service or factory is used to share data between controller.so it would be best to define function in service and factory.
demo:
(function() {
angular.module('app', [])
.service('svc', function() {
var svc = {};
svc.method = function() {
alert(1);
}
return svc;
})
.controller('ctrl', [
'$scope', 'svc', function($scope, svc) {
svc.method();
}
]);
})();
You should not!!!
That defeats the whole purpose of modularity.
If possible try to make the function generic and create a service/factory. Now both the places where you need, use the same generic function defined in service and do their stuff.
Otherwise you can also look at events to make changes accordingly.
Look at this blog post:
http://ilikekillnerds.com/2014/11/angularjs-call-controller-another-controller/
Last but the worst solution is (avoid using this, this is literally an aweful way) is catching the element inside directive and getting its scope and taking the function from it.
Example,
var otherControllerFunc = $(".inside-directive").scope().yourfunc;
I have one question about using of services. I'm creating services in this way
and everything working properly. Here is my code.
var appName = angular.module('appName', ['configuration', 'angularSpinner']);
// this is whay that I creating services.
(function (module) {
var moduleName = function () {
return function(inputVar) {
// some work with
// inputVal variable
return result;
}
};
module.factory("moduleName", [moduleName]);
}(angular.module("appName")));
// in this way I'm using service into controller.
appName.controller('controllerName', function($scope, moduleName) {
});
My question is do I need to set 'moduleName' in 'appName'. Ie like this:
var appName = angular.module('appName', ['configuration', 'angularSpinner', 'moduleName']);
In both cases everything works properly. I would appreciate any comments and recommendations.
Best regards.
My question is do I need to set 'moduleName' in 'appName'. Ie like this:
No you do not, unless you actually create another module. In this case your moduleName is actually your factory name. If you wanted to create another module you would do this.
var myModule = angular.module('myModule', []);
myModule.factory('myFactory', [function(){ /* factory definition */ }]);
var app = angular.module('app', ['myModule']);
// this will now make myFactory available to my app
Your using the factory method which returns a function. If you need a service (a singleton object) then use the service method.
I create my services like this
var app = angular.module('app', []);
app.service('myService', [function(){
var serviceMember = { name: 'something' };
var serviceMethod = function() { };
// revealing module pattern
return {
serviceMember: serviceMember,
serviceMethod: serviceMethod
};
}]);
Yes, You needed
var appName = angular.module('appName', ['configuration', 'angularSpinner', 'moduleName'])
The 'appName' is Main Module name, and the 'moduleName' is sub module name. If you put the 'moduleName' with 'appName', then you can call 'modulname' functions wherever you use the 'appName'.
Main Module :
angular.module('appName',
Sub Module :
, ['configuration', 'angularSpinner', 'moduleName']
The concepts works by Dependency Injection Concept
I am working on an angularJS app and I am trying to stick with the most efficient and widely accepted styles of development in AngularJs.
Currently, I am using this way of declaring my services like so:
app.factory('MyService', function() {
/* ... */
function doSomething(){
console.log('I just did something');
}
function iAmNotVisible(){
console.log('I am not accessible from the outside');
}
/* ... */
return{
doSomething: doSomething
};
});
However, there are numerous examples out there and I am not quite sure which design style to follow. Can someone with extensive knowledge about services explain the reason why a certain style is more relevant than another?
Is what I am doing useful in any way other than restricting the access to certain functions in my service?
I would suggest you layout your factory or service as they do in the angular-seed app, except that app annoyingly only uses value in the services.js boilerplate. However you can adapt the layout they use for controllers, directives and filters.
'use strict';
/* Filters */
angular.module('myApp.filters', []).
filter('interpolate', ['version', function(version) {
return function(text) {
return String(text).replace(/\%VERSION\%/mg, version);
}
}]);
Which means for a service you would do:
'use strict';
/* Services */
angular.module('myApp.filters', []).
service('myservice', ['provider1', 'provider2', function(provider1, provider2) {
this.foo = function() {
return 'foo';
};
}]).
factory('myfactoryprovider', ['myservice', function(myservice) {
return "whatever";
}]);
This has more boilerplate than you absolutely need, but it is minification safe and keeps your namespaces clean.
Than all you have to do is decide which of const, value, factory or service is most appropriate. Use service if you want to create a single object: it gets called as a constructor so you just assign any methods to this and everything will share the same object. Use factory if you want full control over whether or not an object is created though it is still only called once. Use value to return a simple value, use const for values you can use within config.
I don't believe there's an accepted standard but I myself follow this convention:
var myServiceFn = function (rootScope, http) { ... };
...
app.factory('MyService', ['$rootScope', '$http', myServiceFn]);
I feel like this is cleaner than defining the function inline and also allows for proper injection if I ever decide to minify my files. (see http://docs.angularjs.org/tutorial/step_05).
As an example, I've been defining services within modules like so:
angular.module('userModule', [])
.service('userService', function() {
this.user = null;
this.getUser = function() {
return this.user;
};
this.userIsNull = function() {
return (this.user === null);
};
this.signout = function() {
this.user = null;
};
})
I think it is more clear to use the .service rather than the .factory?