How to define controllers in multiple files - AngularJs - javascript

I am trying to define controllers in separate files, but I'm getting the error:
transactionsController not a function got undefined
File structure
I have added files in this sequence
1- common.js
2- transactions.js
Common.js
In common files I have defined
var app = angular.module("spModule", ["ngMessages", "ui.bootstrap"]);
Transactions.js
angular.module('spModule').controller('transactionsController',
['$scope', '$http', function ($scope, $http) {} ]
);
HTML FIle
<body ng-app="spModule" ng-controller="transactionsController">

First, you should get rid of the global app variable. This is not necessary. Second, you have to understand the principle of the angular.module() method.
Using angular.module() with two parameters (e.g. angular.module('my-module', [])) would result in setting a new module with its corresponding dependencies. In contrast, when using angular.module('my-module') the corresponding module is looked up internally and returned to the caller (getting).
The means when you first define you application you might just create the following files and structure.
app.js
angular.module('myApp', []);
FirstController.js
angular.module('myApp').controller('FirstController', function () {});
SecondController.js
angular.module('myApp').controller('SecondController', function () {});
If you now include these files in your html document in this particularly order (at least app.js has to come first), your application works just fine with two separate controllers in two separate files.
Further readings
I can recommend the AngularJS Styleguide on modules for getting more ideas on this topic.

You Can put this controller in seprate file like mycontroller1.js
app.controller('myController', ['$scope',function($scope)
{
$scope.myValue='hello World'
}])
Same like this you can create new js file 'myNewcontroller.js' and can put new controller :
app.controller('myController2', ['$scope',function($scope)
{
$scope.myValue='hello World'
}])
Hope this will help you :) Cheers !!

You can do this stuff by creating modules. Create module and respective controllers. And inject that module to the main app module.
Transactions.js
(function() {
'use strict';
angular.module('tmodule', []);
})();
(function() {
'use strict';
angular.module('tmodule').controller('transactionsController', ['$scope', '$http',
function ($scope, $http){
}]);
})();
Now inject the "tmodule" to your Common.js file-
var app = angular.module("spModule", ["ngMessages", "ui.bootstrap","tmodule"]);

Load your common.js first. Move ng-app directive to <html> tag. Change transaction.js to:
app.controller('transactionsController', TransactionsController)
TransactionsController.$inject = ['$scope','$http']
function TransactionsController($scope, $http) {
};
Just for fun. Let me know what happens.

Related

angular.module called from separate files, does not find Controller [duplicate]

This question already has an answer here:
angular.module requires doesn't work
(1 answer)
Closed 6 years ago.
I am trying to modularize my code and moved controller in a separate file that uses same module. But, it does not load, I made sure the load order is correct.
// app.js
angular.module("app", []);
// LoginCtrl.js
angular.module("app", []).controller("LoginCtrl", function()
{
//doSomeThing
});
If I do var app = angular.module in first file and use the same variable in other files, it works.
// app.js
var app = angular.module("app", []);
// LoginCtrl.js
app.controller("LoginCtrl", function()
{
//doSomeThing
});
If I move all code in one file and use angular.module separately for each component, it works.
// app.js
angular.module("app", []);
angular.module("app", []).controller("LoginCtrl", function()
{
//doSomeThing
});
Am I missing something?
To create a module in AngularJS:
angular.module('app', []);
To get a module in AngularJS:
angular.module('app');
You use the same signature in your code to create and get a module, you mustn't add the injection array as the second argument of the module function when getting a module in another file.
Firstly,there can be only one module in a controller. This is an example var app = angular.module('myApp', []) .controller('Controllername', function () {};
After modulerizing your code, write this in your LoginCtrl.js file:
var app = angular.module("app");
app.controller("LoginCtrl", function() {
...

Passing dependencies to a module angular

So I am somewhat new to angular, but not javascript. I am working with an app someone else wrote and am trying to create a new controller in an existing module. The controllers are almost identical to each other as far as dependencies go. The question I have is how do I pass the same dependencies to both controllers? It seems like you would be able to pass them in like this:
`angular.module('ApertureForm', ['dialogs.main','dialogs.default-translations','ui.bootstrap'])`
When I do that for both modules, the controller returns undefined for whatever reason. Thats where I get stuck. How do you pass in dependencies such as the above code? Any advice would be great.
angular.module('ApertureForm', ['dialogs.main','dialogs.default-translations','ui.bootstrap']) tells AngularJS to initialize an Angular module named ApertureForm and also load other Angular modules as dependencies for the module.
To add dependencies to a controller, you do something like the following:
angular.module('ApertureForm').controller('ControllerName', function($scope, $location, $timeout) {...});
angular.module('ApertureForm') = Get the module named ApertureForm.
Then create a controller called ControllerName. The closure is where you inject dependencies.
To prevent a controller's dependencies from getting renamed on minification, you can do:
angular
.module('ApertureForm')
.controller('ControllerName', ControllerName);
ControllerName.$inject = ['$scope', '$location', '$timeout'];
function ControllerName($scope, $location, $timeout) {...}
Docs: https://docs.angularjs.org/guide/di
In angular.module('ApertureForm',[ you list the modules you want to inject to your module. You list in once for each module you have. If You want to create a controller in one of your modules, then your can use:
var myApp = angular.module('ApertureForm');
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
}]);
$scope here is a dependency for controller
You can read more about it here
AngularJS Controllers and Dependency Injection:
angular
.module('ApertureForm', ['dialogs.main','dialogs.default-translations','ui.bootstrap'])
.controller('FormController', ['$scope', '$http', function($scope, $http) {
// FormController code...
}])
.controller('WebinarController', ['$scope', '$http', function($scope, $http) {
// WebinarController code...
}]);
Thanks to everyone for the help! All of it was very useful in learning the structure of angular and how to properly use the framework. #Yosvel Quintero was able to explain how the module works and why I was getting the error. When dependencies are passed into the module, not the controller, they are available to all controllers as it the module it's self is now aware of the dependencies, which is why I kept getting errors trying to pass them again. Hopefully the answers given in response to the question can help someone learn angular as well. Thanks guys!

Should AngularJS modules be in their own file?

Fairly simple question, I can't seem to find a definitive answer. At the minute I've my module declared in one file :
var module = angular.module("app", ["agGrid", "ngAnimate", "ngSanitize", "ui.bootstrap"]);
and my controller in another :
angular.module("app").controller("mainCtrl", ["$scope", "$timeout", "dateFilter", "$http", "shareDataService", "getDataService", function ($scope, $timeout, dateFilter, $http, shareDataService, getDataService) {
Is this good structure or a waste of time and space?
Single Responsibility
Define 1 component per file.
The following example defines the app module and its dependencies, defines a controller, and defines a factory all in the same file.
Avoid this
angular
.module('app', ['ngRoute'])
.controller('SomeController', SomeController)
.factory('someFactory', someFactory);
function SomeController() { }
function someFactory() { }
The same components are now separated into their own files.
Do this
// app.module.js
angular
.module('app', ['ngRoute']);
// some.controller.js
angular
.module('app')
.controller('SomeController', SomeController);
function SomeController() { }
// someFactory.js
angular
.module('app')
.factory('someFactory', someFactory);
function someFactory() { }
https://github.com/johnpapa/angular-styleguide#style-y001
It's a good practice to keep them separate. This way, you don't end up mixing the module(s) definition and controllers / services / directives.
here you get some of the best practices in angular js -
Instead of slicing your app across horizontals that can't be broken
up, group your code into related bundles. This way if you remove a
module, your app still works.
https://github.com/angular/angular.js/wiki/Best-Practices
Having separate files for each type of component is ideal. I follow the structure in development:
app.js //where the module resides
routes.js //consists of routes
controllers/
services/
factories/
filters/
directives/
Define your module:
var app = angular.module();
Then use 'app' to declare other nested js in separate files, example:
app.directive()
However, in production, it is preferable to use task runner (eg gulp) to combine all the files and minify the final file.

Is it possible to lazy-load and inject angular modules into the app in runtime using angularAMD?

I have ng-grid as a dependency when defining the app:
var app = angular.module('myApp', ['ngGrid']);
But not all my views and controllers need ngGrid, so I was thinking if it could be possible to load and inject ngGrid into the app while defining the controllers which need it?
I tried somthing like this, but it didn't work:
app.js:
var app = angular.module('app',[]);
ProductListCtrl.js:
define(['app', 'ng-grid'], function (app) {
'use strict';
app.register.controller('ProductListCtrl', ['$scope', 'ngGrid', function ($scope) {
name = $injector.get('ngGrid')
$scope.name = name
}]);
});
Any suggestions?
angularAMD provides an ngload RequireJS plugin allowing you to load existing AngularJS modules. Add ngload to your main.js then do:
define(['app', 'ngload!ng-grid'], function (app) { ... }
See documentation for more detail.

AngularJS seed: putting JavaScript into separate files (app.js, controllers.js, directives.js, filters.js, services.js)

I'm using the angular-seed template to structure my application. Initially I put all my JavaScript code into a single file, main.js. This file contained my module declaration, controllers, directives, filters, and services. The application works fine like this, but I'm worried about scalability and maintainability as my application becomes more complex. I noticed that the angular-seed template has separate files for each of these, so I've attempted to distribute my code from the single main.js file into each of the other files mentioned in the title to this question and found in the app/js directory of the angular-seed template.
My question is: how do I manage the dependencies to get the application to work? The existing documentation found here isn't very clear in this regard since each of the examples given shows a single JavaScript source file.
An example of what I have is:
app.js
angular.module('myApp',
['myApp.filters',
'myApp.services',
'myApp.controllers']);
controllers.js
angular.module('myApp.controllers', []).
controller('AppCtrl', [function ($scope, $http, $filter, MyService) {
$scope.myService = MyService; // found in services.js
// other functions...
}
]);
filters.js
angular.module('myApp.filters', []).
filter('myFilter', [function (MyService) {
return function(value) {
if (MyService.data) { // test to ensure service is loaded
for (var i = 0; i < MyService.data.length; i++) {
// code to return appropriate value from MyService
}
}
}
}]
);
services.js
angular.module('myApp.services', []).
factory('MyService', function($http) {
var MyService = {};
$http.get('resources/data.json').success(function(response) {
MyService.data = response;
});
return MyService;
}
);
main.js
/* This is the single file I want to separate into the others */
var myApp = angular.module('myApp'), []);
myApp.factory('MyService', function($http) {
// same code as in services.js
}
myApp.filter('myFilter', function(MyService) {
// same code as in filters.js
}
function AppCtrl ($scope, $http, $filter, MyService) {
// same code as in app.js
}
How do I manage the dependencies?
The problem is caused from you "redeclaring" your application module in all your separate files.
This is what the app module declaration (not sure declaration is the right term) looks like:
angular.module('myApp', []).controller( //...
This is what assignment (not sure if assignment is the right term either) to your application module looks like:
angular.module('myApp').controller( //...
Notice the lack of square brackets.
So, the former version, one with the square brackets, should only be used once, usually in your app.js or main.js. All other associated files — controllers, directives, filters … — should use the latter version, the one without the square brackets.
I hope that makes sense. Cheers!
If you're wanting to put your different parts of your application (filters, services, controllers) in different physical files, there are two things you have to do:
Declare those namespaces (for lack of a better term) in your app.js or in each file;
Refer to those namespaces in each of the files.
So, your app.js would look like this:
angular.module('myApp', ['external-dependency-1', 'myApp.services', 'myApp.controllers'])
.run(function() {
//...
})
.config(function() {
//...
});
And in each individual file:
services.js
angular.module('myApp.services', []); //instantiates
angular.module('myApp.services') //gets
.factory('MyService', function() {
return {};
});
controllers.js
angular.module('myApp.controllers', []); //instantiates
angular.module('myApp.controllers') //gets
.controller('MyCtrl', function($scope) {
//snip...
})
.controller('AccountCtrl', function($scope) {
//snip...
});
All of this can be combined into one call:
controllers.js
angular.module('myApp.controllers', [])
.controller('MyCtrl', function($scope) {
//snip...
});
The important part is that you shouldn't redefine angular.module('myApp'); that would cause it to be overwritten when you instantiate your controllers, probably not what you want.
You get the error because you didn't define myApp.services yet. What I did so far is putting all the initial definitions in one file and then use them in another. Like for your example I would put in:
app.js
angular.module('myApp.services', []);
angular.module('myApp',
['myApp.services',
...]);
That should get rid of the error, though I think you should have a read on the article Eduard Gamonal mentioned in one of the comments.

Categories

Resources