Can I have 2 controllers in AngularJS app - angularjs

I'm building a small search app using Elasticsearch and AngularJS (still learning how to use both). I know this may not be best practice, but for all the AngularJS code, trying to keep all my js code in 1 file.
I would like to use the AngularJS UI Bootstrap Typeahead for an autocomplete feature but a little confused on how I can have 2 controllers for the app OR if I can somehow include the Typeahead in my current controller?
Here is some of my code:
var searchApp = angular.module('searchApp', ['elasticsearch', 'ngSanitize', 'ui.bootstrap']);
searchApp.controller('SearchResultsList', ['$scope', 'searchService', 'filterService', '$sce', function($scope, searchService, filterService, $sce) {
I've included ui bootstrap as a dependency for the app, but since I already have SearchResultsList as my controller, not sure how to include TypeaheadCtrl to it...

Yes you can have as many controllers as you'd like in AngularJS. You need to be careful however (for example passing variables between controllers, $scope.$parent, if applicable)
As well, if you are using type-ahead (or any directive from Angular UI-Bootstrap such as tabset), you need to be careful of child-scopes and primitive scopes creating be Angular-UI-Bootstrap. Always declare scope variables using some holding object so it doesn't get overwritten in primitive scopes in a directive ($scope.data storing your data vs just storing it in $scope)
For including typeahead, this is a simple directive and you've already included its functionality when you included it as a dependency in the module. Just read the documentation and follow it:
https://angular-ui.github.io/bootstrap/

Related

How do I register an Angular Component?

With the current strategy, at the root of each module I have an index.js file defining all of the Angular 1.X pieces are to be included within the application.
A very basic example is:
angular.module('app', [])
.config(require('./app.states'))
.service('appService', require('./app.service'))
.directive('appDirective', require('./app.directive'));
The team has been using directives for stuff that is simply silly. I'm sure you can relate to people stuffing controllers with too much and all the other bad examples for 'not having enough time'.
I'm wanting to start using components over directives for many instances where we're really just wanting a 'smart' template for a state yet it doesn't seem like I can refer to or register a component in the same way that I would the service/directive like in the example above.
In short, using 'appComponent' as the name of the component from within the state definition isn't something that works in the same way ::
angular.module('app', [])
.config(require('./app.states'))
.service('appService', require('./app.service'))
.component('appComponent', require('./app.component'));
What should I try next?
The answer was that in the earlier versions of Angular from 1.5 on, components gained support. As it stands, to register a component within the angular module definition, you still use the directive() and simply require the component in lieu of the directive.
angular.module('app', [])
.config(require('./app.states'))
.service('appService', require('./app.service'))
.directive('appComponent', require('./app.component'));

Angularjs StreamHelperController is not a function

I do understand why angular throws this error but i didn't find a solution that solves my case.
When angular encounter with ng-controller attribute, it tries to find injected controller named as the attribute value.
For example for my case:
Angular tries to find StreamHelperController in the injected controller list, when it doesn not find it, it throws
"StreamHelperController is not a function"
.
Known Solution: Injecting controller before loading view layer.
Controller:
var app = angular.module('myapp');
app.controller('StreamHelperController', ['$scope', function ($scope) {}]);
View:
<div ng-controller="StreamHelperController ">
But the problem occurs when i load view before controller class. And this is my case. So how can i manage and solve this problem ?
ENV:
Angularjs 1.5.8
javascript is synchronous.
controller is the bond|connection between model and view, without it no communication.
Thus, controller not defined at time will freeze the parsing.Try using promise or some other asynchronous trick or provide more info.

Creating custom filters in Angular

I am learning Angular and need to create some custom filters.
Do I create one filters.js file and put all my filters in there similar to all my reusable factory.js?
Eg: I have a utilsFactory.js and I put reusable functions in here.
Does this then get injected into the controllers? Or is this loaded in the $rootscope somewhere?
I have seen many examples on how to create them but not how to store and manage them and how to access them properly
filter.js
angular.module('achApp', [])
.filter('myUpperCase', function(){
return function(value){
return String(value).toUpperCase();
}
});
Controller
(function(){
var DevbController = function($scope, utilsFactory, $filter){
$scope.greeting = 'hello';
};
DevbController.$inject = ['$scope', 'utilsFactory', '$filter'];
angular.module('achApp')
.controller('DevbController', DevbController)
}());
Filters are generally created for use in your templates (HTML). For example:
<p>{{somethingOnScope | myFilter}}</p>
You can use them in your JS files by injecting $filter, and then getting a reference to your filter like: $filter('myFilter');
You can see usage examples in the filter documentation:
https://docs.angularjs.org/api/ng/filter/filter
Where and how exactly you register your filters is a matter of style. I personally try to follow john papa's advice and create only one injectable item per file.
On another subjective note, I prefer to minimize the use of filters, especially custom ones. If you want to use them primarily in your JS, a service/factory feels cleaner to me, and if you're tempted to create one for use in your templates, often you can instead just change the thing before putting it on the scope.

What's the best practice to implement md-toast in a web app?

I'm new to AngularJS and Material.
What's the best practice to implement dynamic Angular Material toast across the entire site? The demo here tells me that I need to include the code in controllers. However, I don't want to have duplicated md-toast code in all my controllers. What's the right thing to do here? Thanks!
You can do a service and inject that service in each controller.
angular.module('toast', ['ngMaterial'])
.service('toastService', function($scope, $mdToast, $document)){
[...]
}
.controller('AppCtrl', function($scope, toastService) {
toastService.showToast(message,params,...);
}
In service you write toast logic in the same way you would in the controller, but instead a string for message, you use variables. Then you can call the function in service passing the message declared in the controller, and other params you want.

scope of 'angular' variable when several apps are declared?

if you have the following:
<html ng-app="outerApp">
<head ng-app="innerApp"></head>
<script>
var outerApp = angular.module("outerApp", []);
var ACtrl = outerApp.controller("ACtrl", function($scope){console.log($scope.name);});
var BCtrl = outerApp.controller("BCtrl",function($scope){console.log($scope.name});
var CCtrl = innerApp.controller.("CCtrl", function($scope){ console.log($scope.name);});
var innerApp = angular.module("innerApp", []);
</scope>
Is this ok? is angular a global variable that will work for declaring modules out of both innerApp and outerApp? Also are there limits to number of ng-app's on a page? And do both ACtrl, and BCtrl have reference to the same $scope?
Thanks
This won't work because:
Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application. To run multiple applications in an HTML document you must manually bootstrap them using angular.bootstrap instead. AngularJS applications cannot be nested within each other.
See documentation
$rootscope,$scope are conceptually global variables, whom you can implement to achieve as global variables for sharing data between the modules,directives,controllers,views.
you should read conceptually DI(Dependency Injection) and how the conceptual framework implements in angular. you can inject the dependencies.
angular.module('modulename',[]);
[] is an array in which you define that module is dependant on the other module. in Other words.
Angular framework concepts works the injectable way DI(Dependency Inject).
however i strongly suggest you, what you trying to achieve is the right path is, you should make a simple custom directive and inject it as a dependency in the angular app.

Resources