AngularJS: Service in different file - angularjs

I'm learning AngularJS following an organization inspired by ng-boilerplate. I create different Angular modules for the different parts of my site.
However, I want to create all common elements (services and directives) under the main module, while having them all be in separate source files.
This code works, but is the module in sessionService.js referencing the same module than app.js, or is it creating a new one with the same name?
app.js
var app = angular.module('myApp', [...])
.config(...)
.controller(...);
sessionService.js
angular.module('myApp', [])
.service('SessionService', function() { ... });

If you call angular.module('myApp', []) multiple times on the same page, you will likely run into errors or conflicts. I never tried that.
However, if you already run angular.module('myApp', []) once. Then you can run angular.module('myApp') (note: without []) to retrieve (refer to) the myApp module you defined earlier.

in controller.js file :
var app = angular.module('myApp',['newService']);
in service.js :
angular.module('newService',[])
.service('someService',function(){
return {
// return something
return null
}
}
});
Do not forget to include both the js files in your HTML:
<script src="controllers/controller.js" type="text/javascript"></script>
<script src="services/service.js" type="text/javascript"></script>

Naming & namespacing is important in any project. Try:
app.js:
var app = angular.module('myApp', ['sessionService', ...])...;
sessionService.js:
angular.module('sessionService', [])
.service('SessionService', ...);
Notice that the module name is in lower camel case while the service object itself is upper camel case. This will help you avoid namespace clashing. Hope that helps.

Related

How to load modules only when required

I am doing angular project,i have a situation that i need to load "ngSanitize" module.The problem is i don't need this module when index page loading.I want to load it only when required.Please help to find out.
Create a seperate module file (app.module.js) in application depends on your requiement...
angular.module("SampleOne", []);
angular.module('SampleTwo', []);
angular.module("SampleThree", []);
angular.module("SampleFour", []);
angular.module('SampleFive', []);
On page loading initialize this module file,
Depends on your requirement call the modules in your application.
Here "SampleFive" is one of the module i have injected ngSanitize.
var app = angular.module('SampleFive', ['ngSanitize'])
app.controller('MyController', function ($scope) {
$scope.Message = "My name is <span><b>Angular Sanitize</b></span>";
});
When we will call "SampleFive" module on a page only ngSanitize module will load.
Refer a below link...
AngularJS Best Practices: Directory Structure

Angular has deprecated the declaration of ng-app without name

Consider the piece of code below:
part of html file:
<body ng-app>
<div ng-controller="MainCtrl">{{name}}</div>
</body>
part of js file:
function MainCtrl($scope) {
$scope.name = "John";
}
I always put my controllers in some module, whose name I define in ng-app. How it works when I don't define any module ?
I just started with angular js and faced the above scenerio.
Declare your app in the DOM with a name:
<html ng-app="myApp">
Next, register your app as a module in your JavaScript:
angular.module("myApp", []);
Note the array as the 2nd argument; this means you're registering a new module, rather than accessing a previously defined module.
Finally, register your controller(s) onto your app:
angular.module("myApp")
.controller("MyCtrl", ["$scope", function($scope) {
// controller code goes here
}]);
Note the lack of the 2nd argument this time, as you're getting the previously defined myApp module.
Your question is answered in the 2nd step of the Angular tutorial. If you're new to Angular, I suggest you start here (at step_00).

Angular JS Problemsss [duplicate]

I am writing a sample application using angularjs. i got an error mentioned below on chrome browser.
Error is
Error: [ng:areq] http://errors.angularjs.org/1.3.0-beta.17/ng/areq?p0=ContactController&p1=not%20a%20function%2C%20got%20undefined
Which renders as
Argument 'ContactController' is not a function, got undefined
Code
<!DOCTYPE html>
<html ng-app>
<head>
<script src="../angular.min.js"></script>
<script type="text/javascript">
function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}
</script>
</head>
<body>
<h1> modules sample </h1>
<div ng-controller="ContactController">
Email:<input type="text" ng-model="newcontact">
<button ng-click="add()">Add</button>
<h2> Contacts </h2>
<ul>
<li ng-repeat="contact in contacts"> {{contact}} </li>
</ul>
</div>
</body>
</html>
With Angular 1.3+ you can no longer use global controller declaration on the global scope (Without explicit registration). You would need to register the controller using module.controller syntax.
Example:-
angular.module('app', [])
.controller('ContactController', ['$scope', function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}]);
or
function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}
ContactController.$inject = ['$scope'];
angular.module('app', []).controller('ContactController', ContactController);
It is a breaking change but it can be turned off to use globals by using allowGlobals.
Example:-
angular.module('app')
.config(['$controllerProvider', function($controllerProvider) {
$controllerProvider.allowGlobals();
}]);
Here is the comment from Angular source:-
check if a controller with given name is registered via $controllerProvider
check if evaluating the string on the current scope returns a constructor
if $controllerProvider#allowGlobals, check window[constructor] on the global window object (not recommended)
.....
expression = controllers.hasOwnProperty(constructor)
? controllers[constructor]
: getter(locals.$scope, constructor, true) ||
(globals ? getter($window, constructor, true) : undefined);
Some additional checks:-
Do Make sure to put the appname in ng-app directive on your angular root element (eg:- html) as well. Example:- ng-app="myApp"
If everything is fine and you are still getting the issue do remember to make sure you have the right file included in the scripts.
You have not defined the same module twice in different places which results in any entities defined previously on the same module to be cleared out, Example angular.module('app',[]).controller(.. and again in another place angular.module('app',[]).service(.. (with both the scripts included of course) can cause the previously registered controller on the module app to be cleared out with the second recreation of module.
I got this problem because I had wrapped a controller-definition file in a closure:
(function() {
...stuff...
});
But I had forgotten to actually invoke that closure to execute that definition code and actually tell Javascript my controller existed. I.e., the above needs to be:
(function() {
...stuff...
})();
Note the () at the end.
I am a beginner with Angular and I did the basic mistake of not including the app name in the angular root element. So, changing the code from
<html data-ng-app>
to
<html data-ng-app="myApp">
worked for me. #PSL, has covered this already in his answer above.
I had this error because I didn't understand the difference between angular.module('myApp', []) and angular.module('myApp').
This creates the module 'myApp' and overwrites any existing module named 'myApp':
angular.module('myApp', [])
This retrieves an existing module 'myApp':
angular.module('myApp')
I had been overwriting my module in another file, using the first call above which created another module instead of retrieving as I expected.
More detail here: https://docs.angularjs.org/guide/module
I just migrate to angular 1.3.3 and I found that If I had multiple controllers in different files when app is override and I lost first declared containers.
I don't know if is a good practise, but maybe can be helpful for another one.
var app = app;
if(!app) {
app = angular.module('web', ['ui.bootstrap']);
}
app.controller('SearchCtrl', SearchCtrl);
I had this problem when I accidentally redeclared myApp:
var myApp = angular.module('myApp',[...]);
myApp.controller('Controller1', ...);
var myApp = angular.module('myApp',[...]);
myApp.controller('Controller2', ...);
After the redeclare, Controller1 stops working and raises the OP error.
Really great advise, except that the SAME error CAN occur simply by missing the critical script include on your root page
example:
page: index.html
np-app="saleApp"
Missing
<script src="./ordersController.js"></script>
When a Route is told what controller and view to serve up:
.when('/orders/:customerId', {
controller: 'OrdersController',
templateUrl: 'views/orders.html'
})
So essential the undefined controller issue CAN occur in this accidental mistake of not even referencing the controller!
This error might also occur when you have a large project with many modules.
Make sure that the app (module) used in you angular file is the same that you use in your template, in this example "thisApp".
app.js
angular
.module('thisApp', [])
.controller('ContactController', ['$scope', function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}]);
index.html
<html>
<body ng-app='thisApp' ng-controller='ContactController>
...
<script type="text/javascript" src="assets/js/angular.js"></script>
<script src="app.js"></script>
</body>
</html>
If all else fails and you are using Gulp or something similar...just rerun it!
I wasted 30mins quadruple checking everything when all it needed was a swift kick in the pants.
If you're using routes (high probability) and your config has a reference to a controller in a module that's not declared as dependency then initialisation might fail too.
E.g assuming you've configured ngRoute for your app, like
angular.module('yourModule',['ngRoute'])
.config(function($routeProvider, $httpProvider) { ... });
Be careful in the block that declares the routes,
.when('/resourcePath', {
templateUrl: 'resource.html',
controller: 'secondModuleController' //lives in secondModule
});
Declare secondModule as a dependency after 'ngRoute' should resolve the issue. I know I had this problem.
I was getting this error because I was using an older version of angular that wasn't compatible with my code.
These errors occurred, in my case, preceeded by syntax errors at list.find() fuction; 'find' method of a list not recognized by IE11, so has to replace by Filter method, which works for both IE11 and chrome.
refer https://github.com/flrs/visavail/issues/19
This error, in my case, preceded by syntax error at find method of a list in IE11. so replaced find method by filter method as suggested https://github.com/flrs/visavail/issues/19
then above controller not defined error resolved.
I got the same error while following an old tutorial with (not old enough) AngularJS 1.4.3. By far the simplest solution is to edit angular.js source from
function $ControllerProvider() {
var controllers = {},
globals = false;
to
function $ControllerProvider() {
var controllers = {},
globals = true;
and just follow the tutorial as-is, and the deprecated global functions just work as controllers.

App/provider circular dependency

I want to use a provider to set some configuration settings at starting up my AngularJs app, but I would like to have the app and the provider in 2 seperate files.
This is how I have it now:
var myApp = angular.module('myApp', []);
myApp.config(function(myServiceProvider) {
....etc.
The provider is defined like this:
angular.module('myApp').provider('myService', function () {
...etc.
If I load the app first the provider is not there yet, and if I load the provider first the app is not there yet.
What would be the best way to solve this?
Your module definition includes module dependencies - not services or providers.
It should be:
var myApp = angular.module('myApp', []);
The config block is always executed after your providers are initialized. There is no circular dependency issue.
File 1: Define module
angular.module('myApp', []);
File 2: Define providers
angular.module('myApp').provider('myService',function() {...});
File 3: Define config block
angular.module('myApp').config(function(myServiceProvider) { ... });
HTML:
<script src="/angular.js"></script>
<script src="/file1.js"></script>
<script src="/file2.js"></script>
<script src="/file3.js"></script>
Order of the files is important.
in your first file:
var myApp = angular.module('myApp', []);
myApp.config(function(myServiceProvider) {
....etc.
and in your second file:
myApp.provider('myService', function () {
...etc.
The variable myApp is a global variable and you can access to this everywhere in your website.
You can take a look at the Yeoman project, it's a generator which create your angularjs app structure and add lot of cool features.

What is the benefit of defining Angular app?

In some AngularJS tutorials, angular app is defined as:
myApp = angular.module("myApp",[]);
But we can also do without it. The only difference I can see is when we define controller, we can't use idiom:
myApp.controller("myCtrl",function(){ })
but has to use
function myCtrl (){}
Is there any other benefits of defining myApp explicitly, given that I will only create a single app for my site? If I don't define myApp, then where my modules are attached to?
If there is, how I can recreate myApp in testing with Jasmin?
You can define controllers in (at least) 3 ways:
Define the controller as a global var (stored on the window object)
function Ctrl() {}
which is the same as doing:
window.Ctrl = function () {}
Create a module and use the returned instance to create new controllers:
var app = angular.module('app', []);
app.controller('Ctrl', function() {});
Create the controllers directly on the module without storing any references (the same as 2 but without using vars):
angular.module('app', []);
angular.module('app').controller('Ctrl', function() {});
From Angular's point of view, they all do the same, you can even mix them together and they will work. The only difference is that option 1 uses global vars while in options 2 and 3 the controllers are stored inside an Angular's private object.
I understand where you're coming from since the explanation for bootstrapping your Angular is all over the place. Having been playing with Angular only for a month (I'll share what I know anyways), I've seen how you have it defined above. I was also in the same scenario where I only have to define myApp once and not have multiple ones.
As an alternative, you can do something like this below. You'll notice that the Angular app and the controller doesn't have to live by the same namespace. I think that is more for readability and organization than anything.
JS:
window.app = {};
/** Bootstrap on document load and define the document along with
optional modules as I have below.
*/
angular.element(document).ready(function () {
app.ang = angular.bootstrap(document, ['ngResource', 'ngSanitize']);
// OR simply, works similarly.
// angular.bootstrap(document, []);
});
/** Define Angular Controller */
app.myController= function ($scope, $resource, $timeout) {
};
HTML:
<div role="main" ng-controller="app.myController"></div>
you have to define the app with angular.module anyway. myApp.controller and function myCtrl are the same..

Resources