as you can see I have opened .xml file and parsed it to a xmlDoc. What I am trying to achieve is that this xmlDoc will be accessible from the whole script(I want to make some functions later which will be displaying elements from .xml to a screen). I searched the web and find that it is possible via global variable $rootScope but couldn't implement it correctly. I hope you guys can help me. Thanks.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body ng-app="myApp">
<p id="title">asd</p>
<button name="opt1" ng-click="">YES</button>
<button name="opt2" ng-click="">NO</button>
<script>
var app = angular.module('myApp', []);
var parser, xmlDoc;
app.run(function($rootScope, $http) {
text = $http.get("file.xml").then(function(response) {
return response.data;
}).then(function(text) {
parser = new DOMParser();
xmlDoc = parser.parseFromString(text,"text/xml");
document.getElementById("title").innerHTML =
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
});
});
</script>
</body>
</html>
There are many ways in angular to declare and use a global variable.
examples:
1. By using $rootScope.
we need to add a dependency in our controller or service like:
app.controller('myCtrl', ['$rootScope', '$scope', function($rootScope, $scope){
$rootScope.yourVar = 'YourValue';
....
....
}]);
and then You can use this `yourVar` variable anywhere in your code.
Another way is by using angular factory or servive.
app.factory('factoryObj', ['$scope', function($scope){
let factoryObj.yourVar = 'yourValue';
return factoryObj;
}]);
Now in any controller or any other service, by using this factoryObj as a dependency and then inside that controller or service we can use factoryObj.yourVar as a variable. as:
app.controller('myCtrl',['$rootScope','$scope','factoryObj'function($rootScope,$scope, factoryObj){
console.log('factoryObj.yourVar value: ',factoryObj.yourVar);
}]);
I am trying to get FirstCtrl data in SecondCtrl, but there is no response in SecondCtrl, Please help me to solve this
I Have tried to use $broadcast and $emit on $rootscope. but there is not data coming on $on
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('FirstCtrl', function( $scope, $rootScope) {
$scope.firstName = 'Ganpat';
//$rootScope.$emit('firstName', $scope.firstName);
$rootScope.$broadcast('firstName:broadcast', $scope.firstName);
});
myApp.controller('SecondCtrl', function( $scope, $rootScope){
$rootScope.$on('firstName:broadcast', function(event,data){
$scope.firstName = data;
console.log(data);
});
});
</script>
<body>
<div ng-app="myApp">
<div ng-controller="FirstCtrl">
<input type="text" ng-model="firstName">
<br>Input is : <strong>{{firstName}}</strong>
</div>
<hr>
<div ng-controller="SecondCtrl">
Input should also be here: {{firstName}}
</div>
</div>
</body>
</html>
Code now compiles and runs properly. You can cut and past this into fiddler and run.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
myApp.factory('UserService', function () {
var self = this;
var firstName = '';
self.SetFirstName = function (name) { firstName = name; }
self.GetFirstName = function () { return firstName; }
return self;
});
myApp.controller('FirstCtrl', ['$scope', 'UserService', function ($scope, UserService) {
UserService.SetFirstName("coolMan");
}]);
myApp.controller('SecondCtrl', ['$scope', 'UserService', function ($scope, UserService) {
$scope.firstNameTest = '';
$scope.service = UserService;
$scope.$watch('service.GetFirstName()', function (newVal) {
console.log("New Data", newVal)
$scope.firstNameTest = newVal;
});
}]);
</script>
<body>
<div ng-app="myApp">
<div ng-controller="FirstCtrl">
<input type="text" ng-model="firstName">
<br>
Input is : <strong>{{firstName}}</strong>
</div>
<hr>
<div ng-controller="SecondCtrl">
Input should also be here: {{firstNameTest}}
</div>
</div>
</body>
</html>
EDIT
Addressing OPS comment.
I know this method will work and it will give a correct result, but i
have studied the $rootscope and event $emiter and $broadcast will do
this trick, so if you know about that then please tell me, thank you
for your answer.
What you want to do is a bad idea. Your method forces a tighter coupling between controllers. By working on the rootscope you are forcing all controllers to rely on a certain Item being in rootscope. This is bad because controllers are not self contained modules.
By passing around a service you can decouple the controllers. Meaning that they can be used as view controllers, directive controllers, pretty much anything that requires an isolated module.
Also using a service you can now cache the result, perform centralized business logic on it, and encapsulate how you get the data. This cannot be done easily on the rootscope.
To sum it up, I will not show you a terrible way of doing what you want done. It is not good and will let other people whom look at this post use bad practices.
I'm having trouble getting a $scope variable to trigger the screen to rebind. Yes, I've tried calling $scope.$apply() after assigning $scope.value = value; Yes, I've tried calling $digest() manually after the assignment; I get the error "$rootScope:inprog] $digest already in progress.
So What I've done is try to get my $rootScope.$on('message'function(){}) listener to create a secondary $broadcast to all scopes to try and get to the bottom of this; however, my $scope's registration of the event is not firing and I'm thinking this might be related to the same issue....maybe not. At any rate, here's my codez.
I'd build a fiddle but it's currently blocked by network policy.
Manifest:
[config]
[index.html]
[foo.html]
[ctrl]
[config] (a couple of attempted hacks. They're marked with comments)
var kata = angular.module('kata',[
'ngRoute'
]).run(['$rootScope',
function($rootScope){
$rootScope.$on('message:foo',function(event,data){
$rootScope.$broadcast('message:bar',['foo1','foo2','foo3']);//send secondary msg
$rootScope.data = data; //Hack #1: When I couldn't get $scope to rebind, I tried to use $rootScope;still doesn't rebind.
});
}]);
kata.config(['$routeProvider',
function($routeProvider){
$routeProvider
.when('/Foo',{
templateUrl: 'foo.html',
controller: 'FooCtrl'
});
}]);
[index] (nothing funny here)
<html ng-app="kata">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"></meta>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<script src="./routingConfig.js"></script>
<script src="./controllers.js"></script>
</head>
<body>
<div class="view-container">
<div ng-view class="view-frame"></div>
</div>
</body>
</html>
[foo.html] (nothing funny here)
A couple of tests with a couple of $scope variables attached to same stuff.
Neither of these update
<div>
This page is for capturing Data
Data: {{data}}
<hr />
<ul>
<li ng-repeat="foo in foos">
<span>Foo Found!</span>
</li>
</ul>
</div>
[ctrl] (created several variables on scope trying to attack this problem in different ways)
var kataCtrl= kata.controller("FooCtrl",
[ '$scope', '$http','$rootScope','$location'
,function($scope, $http, $rootScope , $location) {
$scope.data = "Foo";
$scope.data1 = "[placeholder]";
$scope.foos = [];
//fires, assigns, view does not update
$scope.$watch(function(){
return $rootScope.data;
}, function(){
$scope.foos = ['data','foo','bar','baz'];<=Assignment succeeds. View does not update
$scope.$apply();//<=Does nothing apparent; View does not update
$scope.$digest();//<= Console Error. Already in digest loop
},true);
//does not fire
$scope.$on('message:foo',function(event,data){ //<= This never catches
$scope.data = data;
});
//fires, assigns, View does not update
$rootScope.$on('message:bar',function(event,data){
$scope.foos = ['data','foo','bar','baz'];
$scope.foo1 = data.element1;
$scope.data = "[Foos returned from $rootScope]";
$scope.$apply();//<= Does not help. Changing to $scope.$digest() indicates already in digest loop
});
}]);
So as a recap, $rootScope.$on() inside my config is firing. It is assigning values to variables on $rootScope properly. $rootScope.$broadcast is generating a secondary message. The controller's $scope.$on registration of the message does not catch.The controller's $rootScope.$on registration fires and assigns values on $scope, but the view does not rebind. Calling $scope.$apply() does not help. Calling $scope.$digest() merely reports that a digest loop is currently running.
Scoped variables are assigned to but the view never rebinds.
What in the wide wide world of sports is going on here?
I think the problem is you are broadcasting 'message:bar' and listening to 'message:foo' in controller. I have made simplified version of your code. You can see thet my code emits event to root scope and gots broadcasted event in child scope:
<html ng-app="kata">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"></meta>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
</head>
<body>
<div class="view-container" ng-controller="FooCtrl">
<div class="view-frame">
<div>
This page is for capturing Data
<br>
Data: {{data}}
<hr />
<ul>
<li ng-repeat="foo in foos">
<span>Foo Found!</span>
</li>
</ul>
</div>
</div>
</div>
<script>
var kata = angular.module('kata',[
'ngRoute'
]).run(['$rootScope',
function($rootScope){
$rootScope.$on('message:foo',function(event,data){
$rootScope.$broadcast('message:bar',['Data', 'from', 'root', 'scope']);//send secondary msg
});
}]);
kata.controller("FooCtrl",
[ '$scope', '$http','$rootScope','$location'
,function($scope, $http, $rootScope , $location) {
$scope.data = "Foo";
$scope.data1 = "[placeholder]";
$scope.foos = [];
$scope.$on('message:bar',function(event,data){
$scope.data = data;
});
$scope.$emit('message:foo');
}]);
</script>
</body>
</html>
This is a long shot, but has anyone seen this error before? I am trying to add 'Transporters' using express, angular and mongoDB. I get this error whenever I access a page ruled by the transporters controller:
Error: [ng:areq] http://errors.angularjs.org/1.2.12/ng/areq?p0=TransportersController&p1=not%20aNaNunction%2C%20got%20undefined
at Error (native)
at http://localhost:3000/lib/angular/angular.min.js:6:450
at tb (http://localhost:3000/lib/angular/angular.min.js:18:360)
at Pa (http://localhost:3000/lib/angular/angular.min.js:18:447)
at http://localhost:3000/lib/angular/angular.min.js:62:17
at http://localhost:3000/lib/angular/angular.min.js:49:43
at q (http://localhost:3000/lib/angular/angular.min.js:7:386)
at H (http://localhost:3000/lib/angular/angular.min.js:48:406)
at f (http://localhost:3000/lib/angular/angular.min.js:42:399)
at http://localhost:3000/lib/angular/angular.min.js:42:67
The transporters controller looks like this:
'use strict';
angular.module('mean.transporters').controller('TransportersController', ['$scope', '$routeParams', '$location', 'Global', 'Transporters', function ($scope, $routeParams, $location, Global, Transporters) {
$scope.global = Global;
$scope.create = function() {
var transporter = new Transporters({
name: this.name,
natl_id: this.natl_id,
phone: this.phone
});
transporter.$save(function(response) {
$location.path('transporters/' + response._id);
});
this.title = '';
this.content = '';
};
$scope.remove = function(transporter) {
if (transporter) {
transporter.$remove();
for (var i in $scope.transporters) {
if ($scope.transporters[i] === transporter) {
$scope.transporters.splice(i, 1);
}
}
}
else {
$scope.transporter.$remove();
$location.path('transporters');
}
};
$scope.update = function() {
var transporter = $scope.transporter;
if (!transporter.updated) {
transporter.updated = [];
}
transporter.updated.push(new Date().getTime());
transporter.$update(function() {
$location.path('transporters/' + transporter._id);
});
};
$scope.find = function() {
Transporters.query(function(transporters) {
$scope.transporters = transporters;
});
};
$scope.findOne = function() {
Transporters.get({
transporterId: $routeParams.transporterId
}, function(transporter) {
$scope.transporter = transporter;
});
};
}]);
In my views I call the list and create methods. They generate the above error
I got this from the angular docs for ng:areq though still can't figure what's going on
AngularJS often asserts that certain values will be present and truthy
using a helper function. If the assertion fails, this error is thrown.
To fix this problem, make sure that the value the assertion expects is
defined and truthy.
Here's the view that calls the controller public/views/transporters/list.html:
<section data-ng-controller="TransportersController" data-ng-init="find()">
<ul class="transporters unstyled">
<li data-ng-repeat="transporter in transporters">
<span>{{transporter.created | date:'medium'}}</span> /
<h2><a data-ng-href="#!/transporters/{{transporter._id}}">{{transporter.name}}</a></h2>
<div>{{transporter.natl_id}}</div>
<div>{{transporter.phone}}</div>
</li>
</ul>
<h1 data-ng-hide="!transporters || transporters.length">No transporters yet. <br> Why don't you Create One?</h1>
</section>
Transporters service code:
angular.module('transporterService', [])
.factory('Transporter', ['$http', function($http){
// all return promise objects
return {
get: function(){
return $http.get('/api/transporters');
},
create: function(transporterData){
return $http.post('/api/transporters', transporterData);
},
delete: function(id){
return $http.delete('/api/transporters/'+id);
}
};
}]);
I experienced this error once. The problem was I had defined angular.module() in two places with different arguments.
Eg:
var MyApp = angular.module('MyApp', []);
in other place,
var MyApp2 = angular.module('MyApp', ['ngAnimate']);
I've gotten that error twice:
1) When I wrote:
var app = module('flapperNews', []);
instead of:
var app = angular.module('flapperNews', []);
2) When I copy and pasted some html, and the controller name in the html did not exactly match the controller name in my app.js file, for instance:
index.html:
<script src="app.js"></script>
...
...
<body ng-app="flapperNews" ng-controller="MainCtrl">
app.js:
var app = angular.module('flapperNews', []);
app.controller('MyCtrl', ....
In the html, the controller name is "MainCtrl", and in the js I used the name "MyCtrl".
There is actually an error message embedded in the error url:
Error: [ng:areq]
http://errors.angularjs.org/1.3.2/ng/areq?p0=MainCtrl&p1=not%20a%20function%2C%20got%20undefined
Here it is without the hieroglyphics:
MainCtrl not a function got undefined
In other words, "There is no function named MainCtrl. Check your spelling."
I ran into this issue when I had defined the module in the Angular controller but neglected to set the app name in my HTML file. For example:
<html ng-app>
instead of the correct:
<html ng-app="myApp">
when I had defined something like:
angular.module('myApp', []).controller(...
and referenced it in my HTML file.
you forgot to include the controller in your index.html. The controller doesn't exist.
<script src="js/controllers/Controller.js"></script>
I had same error and the issue was that I didn't inject the new module in the main application
var app = angular.module("geo", []);
...
angular
.module('myApp', [
'ui.router',
'ngResource',
'photos',
'geo' //was missing
])
Check the name of your angular module...what is the name of your module in your app.js?
In your TransportersController, you have:
angular.module('mean.transporters')
and in your TransportersService you have:
angular.module('transporterService', [])
You probably want to reference the same module in each:
angular.module('myApp')
I had this error too, I changed the code like this then it worked.
html
<html ng-app="app">
<div ng-controller="firstCtrl">
...
</div>
</html>
app.js
(function(){
var app = angular.module('app',[]);
app.controller('firstCtrl',function($scope){
...
})
})();
You have to make sure that the name in module is same as ng-app
then div will be in the scope of firstCtrl
The same problem happened with me but my problem was that I wasn't adding the FILE_NAME_WHERE_IS_MY_FUNCTION.js
so my file.html never found where my function was
Once I add the "file.js" I resolved the problem
<html ng-app='myApp'>
<body ng-controller='TextController'>
....
....
....
<script src="../file.js"></script>
</body>
</html>
:)
I've got that error when the controller name was not the same (case sensitivity!):
.controller('mainCOntroller', ... // notice CO
and in view
<div class="container" ng-controller="mainController"> <!-- notice Co -->
I got this same error when I included the entire controller file name in the Routes like this:
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html',
controller: 'mainController.js'
})
.when('/portfolio', {
templateUrl: 'portfolio.html',
controller: 'mainController.js'
})
});
When it should be
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html',
controller: 'mainController'
})
.when('/portfolio', {
templateUrl: 'portfolio.html',
controller: 'mainController'
})
});
Angular takes certain things you name like the app and controller and expounds on them in directives and across your app, take care to name everything consistently and check for this when debugging
I know this sounds stupid, but don't see it on here yet :). I had this error caused by forgetting the closing bracket on a function and its associated semi-colon since it was anonymous assigned to a var at the end of my controller.
It appears that many issues with the controller (whether caused by injection error, syntax, etc.) cause this error to appear.
This happened to me when I have multiple angular modules in the same page
I encountered this error when I used partial views
One partial view had
<script src="~/Scripts/Items.js"></script>
<div ng-app="SearchModule">
<div ng-controller="SearchSomething" class="col-md-1">
<input class="searchClass" type="text" placeholder="Search" />
</div>
</div>
Other had
<div ng-app="FeaturedItems" ng-controller="featured">
<ul>
<li ng-repeat="item in Items">{{item.Name}}</li>
</ul>
</div>
I had them in same module with different controller and it started working
I had the same error in a demo app that was concerned with security and login state. None of the other solutions helped, but simply opening a new anonymous browser window did the trick.
Basically, there were cookies and tokens left from a previous version of the app which put AngularJS in a state that it was never supposed to reach. Hence the areq assertions failed.
There's also another way this could happen.
In my app I have a main module that takes care of the ui-router state management, config, and things like that. The actual functionality is all defined in other modules.
I had defined a module
angular.module('account', ['services']);
that had a controller 'DashboardController' in it, but had forgotten to inject it into the main module where I had a state that referenced the DashboardController.
Since the DashboardController wasn't available because of the missing injection, it threw this error.
In my case I included app.js below the controller while app.js should include above any controller like
<script src="js/app.js"></script>
<script src="js/controllers/mainCtrl.js"></script>
I had done everything right other than setting controller in $stateProvider. I used filename rather than variable name.
Following code is wrong:
formApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('management', {
url: '/management',
templateUrl: 'Views/management.html',
controller: 'Controllers/ManagementController.js'
});
and this is the right approach;
formApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('management', {
url: '/management',
templateUrl: 'Views/management.html',
controller: 'ManagementController'
});
Make sure you noticed;
controller: 'ManagementController'
And for those who are curious about my controller file ManagementController.js, it looks like the this;
formApp.controller('ManagementController', ['$scope', '$http', '$filter', '$state',function(scope, http, filter, state) {
scope.testFunc = function() {
scope.managementMsg = "Controller Works Fine.";
};
}]);
For those who want a quick-start angular skeleton for above example check this link https://github.com/zaferfatih/angular_skeleton
The error will be seen when your controller could not be found in the application. You need to make sure that you are correct using values in ng-app and ng-controller directives
This happened to me when using ng-include, and the included page had controllers defined. Apparently that's not supported.
Controller loaded by ng-include not working
I have made a stupid mistake and wasted lot of time so adding this answer over here so that it helps someone
I was incorrectly adding the $scope variable(dependency)(was adding it without single quotes)
for example what i was doing was something like this
angular.module("myApp",[]).controller('akshay',[$scope,
where the desired syntax is like this
angular.module("myApp",[]).controller('akshay',['$scope',
// include controller dependency in case of third type
var app = angular.module('app', ['controller']);
// first type to declare controller
// this doesn't work well
var FirstController = function($scope) {
$scope.val = "First Value";
}
//Second type of declaration
app.controller('FirstController', function($scope) {
$scope.val = "First Controller";
});
// Third and best type
angular.module('controller',[]).controller('FirstController', function($scope) {
$scope.val = "Best Way of Controller";
});
I have a setup with an ng-view (an admin panel) that lets me display orders. I have a search box outside of ng-view that I would like to use to modify my json request. I've seen some posts on accessing things such as the title but was not able to get them to work - perhaps outdated.
Main app stuff:
angular.module('myApp', ['myApp.controllers', 'myApp.filters', 'myApp.services', 'myApp.directives', 'ui.bootstrap']).
config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: '/partials/order/manage.html',
controller: 'ManageOrderCtrl'
}).
when('/order/:id', {
templateUrl: '/partials/order/view.html',
controller: 'ViewOrderCtrl'
}).
otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
}]);
Manage controller:
angular.module('myApp.controllers', [])
.controller('ManageOrderCtrl', ['$scope', '$http', '$dialog', 'config', 'Page', function($scope, $http, $dialog, config, Page) {
// would like to have search value from input #search available here
var getData = function() {
$http.get('/orders').
success(function(data, status, headers, config) {
$scope.orders = data.orders;
});
};
getData();
})
View:
<body ng-app="myApp" >
<input type="text" id="search">
<div class="ng-cloak" >
<div ng-view></div>
</div>
</body>
If you're going to access stuff outside the <div ng-view></div>, I think a better approach would be to create a controller for the outer region as well. Then you create a service to share data between the controllers:
<body ng-app="myApp" >
<div ng-controller="MainCtrl">
<input type="text" id="search">
</div>
<div class="ng-cloak" >
<div ng-view></div>
</div>
</body>
(ng-controller="MainCtrl" can also be placed on the <body> tag - then the ng-view $scope would be a child of the MainCtrl $scope instead of a sibling.)
Creating the service is as simple as this:
app.factory('Search',function(){
return {text:''};
});
And it's injectable like this:
app.controller('ManageOrderCtrl', function($scope,Search) {
$scope.searchFromService = Search;
});
app.controller('MainCtrl',function($scope,Search){
$scope.search = Search;
});
This way you don't have to rely on sharing data through the global $rootScope (which is kinda like relying on global variables in javascript - a bad idea for all sorts of reasons) or through a $parent scope which may or may not be present.
I've created a plnkr that tries to show the difference between the two solutions.
You can use scope hierarchies.
Add an "outer" ng-controller definition to your HTML like this:
<body ng-controller="MainCtrl">
It will become the $parent scope. But you do not need to share data by using a service. You don't even need to use the $scope.$parent scope. You can use scope hierarchies. (See the Scope Hierarchies section on that page). It is really easy.
In your MainCtrl, you may have this:
$scope.userName = "Aziz";
Then in any controller that is nested within MainCtrl (and does not override the userName in its own scope) will have userName also! You can use in in the view with {{userName}}.
Try this...
View:
<body ng-app="myApp" >
<input type="text" id="search" ng-model="searchQuery" />
<div class="ng-cloak" >
<div ng-view></div>
</div>
</body>
Using it in your controller:
$http.get('/orders?query=' + $scope.searchQuery).
success(function(data, status, headers, config) {
$scope.orders = data.orders;
});
Basically, you can do that with anything INSIDE ng-app... Move your ng-app to the html tag and you can edit the title as well!