i am new to AngularJS so please forgive me this dump question.
i have error
Cannot set property 'test' of undefined
angularjs
var App = angular.module('StartModule', []);
App.controller('ModalDemoCtrl', [
function($scope) {
$scope.test = function() {
alert("12312");
}
}
]);
html
<body ng-app="StartModule">
<div ng-controller="ModalDemoCtrl">
<div ng-click="test()">11111</div>
</div>
<body>
You just miss $scope to controller's second argument:
var App = angular.module('StartModule', []);
App.controller('ModalDemoCtrl', [ $scope, function($scope) {
$scope.test = function() {
alert("12312");
}
}]);
You're missing the $scope dependency, you need to inject it in your controller :
App.controller('ModalDemoCtrl', ['$scope'
function($scope) {
That's why the $scope variable is undefined, you're not actually injecting any dependency in it.
This uses the Inline Array Annotation: https://docs.angularjs.org/guide/di
Related
I found in Controller, we use $scope, here is the link (http://www.w3schools.com/angular/tryit.asp?filename=try_ng_controller).
I change $scope to this, it cannot work.
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
However, I found in Service, we use this, here is the link (http://www.w3schools.com/angular/tryit.asp?filename=try_ng_services_custom).
In hexafy service, I change this to $scope, it cannot work.
<script>
var app = angular.module('myApp', []);
app.service('hexafy', function() {
this.myFunc = function (x) {
return x.toString(16);
}
});
app.controller('myCtrl', function($scope, hexafy) {
$scope.hex = hexafy.myFunc(255);
});
</script>
Does my above summary correct? If not, what should be correct summary considering all kinds of possible.
You can use this instead of $scope in controller as well. They have brought in controller as syntax(from Angular 1.2). You can attach data to this(Here controller holds the data). But internally it will be attached to $scope only, but you don't have to attach it manually. It has to be declared in html like this , controller is declared as main , so we have to refer to data in html using main.
<div ng-controller="MainCtrl as main">
{{ main.title }}
</div>
app.controller('MainCtrl', function ($scope) {
this.title = 'Some title';
console.log("Title" + $scope.main.title); // It will print some title in the console.
});
I have this controller A which I'm trying to inject in every other controller.
What controller A does is, it communicates with a factory (which does some authentication services, communicates with database)
My factory looks like this and I named it myFactoryServices.js and included the link to it in my index page.
(function() {
angular
.module('myApp.myFactoryServices', [])
.factory('FactoryService', ["$http", "$location", function($http, $location){
var my = this;
my.someFunction = function()
{
//communiate with backend and return data
}
return my;
}]);
})();
and my Controller A looks like this:
(function() {
angular
.module('myApp.ControlA', [])
.controller('ControllerA', function($scope,$routeParams, FactoryService) {
var my = this;
FactoryService.someFunction();
});
})();
And I am trying to inject this controller in every other controller, but it does not work. I am pretty new to this kind of programming, can anyone tell me where I made mistake?
This is how I tried injecting a controller into another.
(function() {
angular
.module('myApp.ControlB', [])
.factory('ControllerBService', function($http) {
var baseUrl = 'backendurl/';
return {
getInfo: function() {
return $http.get(baseUrl+ 'getInfo');
}
};
})
.controller('ControllerB', function($scope,$routeParams, ControllerBService,ControllerA) {
var my = this;
});
})();
No error is coming, and the controller is not getting injected as I am not able to use those factory services. is this the correct method?
First of all you cannot inject controller to another controller, and One simple solution would be, instead of having each angular modules for each components, declare a module and add the factory service to controllers as dependency.
Code:
var app = angular.module('myApp', []);
app.factory('FactoryService', ["$http", "$location", function($http, $location){
var my = this;
my.someFunction = function()
{
//communiate with backend and return data
}
return my;
}]);
app.controller('ControllerA', function($scope,$routeParams, FactoryService)
{
var my = this;
FactoryService.someFunction();
});
app.controller('ControllerB', function($scope,$routeParams, FactoryService)
{
var my = this;
FactoryService.someFunction();
});
Controllers are not injectable, because controller is not singleton. Controllers are constructor functions used to create instances of controllers. For example you can have multiple instances of one controller in your app:
angular.module('app', []);
angular
.module('app')
.controller('Example', function () {
this.x = Math.random();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<div ng-app="app">
First instance: <br>
<div ng-controller="Example as Ex1">
{{Ex1.x}}
</div>
Second instance: <br>
<div ng-controller="Example as Ex2">
{{Ex2.x}}
</div>
</div>
So if you want to share some behavior between controller you should use factory instead.
To inject a controller into another controller, use the $controller service.
app.controller('ControllerB', function($scope,$routeParams, $controller) {
var my = this;
$scope.ctrlA = $controller("ControllerA", {$scope: $scope});
});
The above example creates an instance of ControllerA as ctrlA with its $scope injected with the scope of the parent controller.
For more information, see AngularJS $controller Service API Reference.
I have an index page wherein I define two controllers. I want to call one main controller always (should be rendered always) and the other is called only for specific sub URL calls. Should I make one nested within another, or I can keep them independent of each other? I don't have access to change routes or anything, only the controller.
Right now when I use the template (HTML) mentioned, it calls/renders both controllers, even though url is say /index
Only for /index/subPage, I want both controllers to be rendering.
/index
/index/subPage
HTML:
<div ng-controller="MainCtl" ng-init=initMain()>
<p> Within ctller2 {{results}} </p>
</div>
<div ng-controller="Ctller2"> <!-- should not be displayed unless /subPage/mainUrl is rendering -->
<p> Within ctller2 {{results}} </p>
</div>
JS:
app.controller('MainCtl', ['$scope', '$http', '$location', function ($scope, $http, $location) {
$http.get('xx/mainUrl').then(function(data) {
$scope.results = someDataJSON;
console.log(someDataJSON);
});
$scope.initMain = function() {
$scope.initMethods();
}
}]);
app.controller('Ctller2', ['$scope', '$http', '$location', function ($scope, $http, $location) {
// This controller gets initialized/rendered/called even when xx/mainUrl is called, and when xx/subPage/mainUrl is called too..
$http.get('xx/subPage/mainUrl').then(function(data) {
$scope.results = someDataJSON;
console.log(someDataJSON);
})
$http.get('xx/subPage').then(function(data) {
$scope.results = data.data;
console.log(data);
})
angular.element(document).ready(function () {
alert('Hello from SubCtl, moving over from main controller to here');
});
}]);
What am I doing wrong? I'm new to Angular.js
You can conditionally initiate a controller using ng-if. So you could try something like this:
<body ng-controller="MainCtrl">
<div ng-controller="ctrl1">{{hello}}</div>
<div ng-controller="ctrl2" ng-if="showCtrl2">{{hello}}</div>
</body>
and then set the value of the variable in a parent controller by checking the current url using $location.path()
var app = angular.module('plunker', []);
app.config(function($locationProvider){
$locationProvider.html5Mode(true);
});
app.controller('MainCtrl', function($scope, $location) {
$scope.showCtrl2 = ($location.path() === 'my path');
});
app.controller('ctrl1', function($scope){
$scope.hello = 'ctrl1 says hello';
});
app.controller('ctrl2', function($scope){
$scope.hello = 'ctrl2 says hello';
});
But it's a bit hacky and for a larger project a more robust solution would require using something like ui.router.
I want to know that can we communicate between two different controllers in AngularJS. Suppose I have Two modules,
Plunker: http://plnkr.co/edit/if0MQwlx9WHrD8XnMi2t?p=preview
1. var app = angular.module('fistModule', []);
app.controller('first', function ($scope) {
$scope.firstMethod= function () {
//my code}
} )
2. var newapp = angular.module('secondModule,[]');
newapp.controller('second', function ($scope) {
$scope.secondMethod= function () {
//my code}
Is there way to communicate between controllers of two different modules.
My Code:
JS:
angular.module('myApp', [])
.controller('ParentCtrl', ['$scope',
function($scope) {
$scope.message = "Child updated from parent controller";
$scope.clickFunction = function() {
$scope.$broadcast('update_parent_controller', $scope.message);
};
}
]);
angular.module('myNewApp', [])
.controller('ChildCtrl', ['$scope',
function($scope) {
$scope.message = "Some text in child controller";
$scope.$on("update_parent_controller", function(event, message) {
$scope.message = message;
});
}
])
HTML:
<div ng-app="myApp" ng-controller="ParentCtrl">
<div ng-app="myNewApp" ng-controller="ChildCtrl">
<p>{{message}}</p>
</div>
<button ng-click="clickFunction()">Click</button>
</div>
As #JB Nizet says, you do it the exact same way. You use a service to communicate between two controllers.
One module needs to have the other module as a dependency. This is always a one-way dependency. I have made secondModule a dependency of firstModule.
As well, the value in the service is stored in an object called data. This is because JavaScript does not pass values by reference -- but does pass objects by reference. So this is a form of boxing.
angular.module('firstModule', ['secondModule'])
.controller('FirstController', FirstController)
.service('sharedData', SharedData);
FirstController.$inject = ['sharedData'];
function FirstController(sharedData) {
this.data = sharedData.data;
}
function SharedData() {
this.data = {
value: 'default value'
}
}
angular.module('secondModule', [])
.controller('SecondController', SecondController);
SecondController.$inject = ['sharedData'];
function SecondController(sharedData) {
this.data = sharedData.data;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="firstModule">
<div ng-controller="FirstController as vm">
First Controller in module firstModule<br>
<input type=text ng-model="vm.data.value" />
</div>
<div ng-controller="SecondController as vm">
Second Controller in module secondModule<br>
{{vm.data.value}}
</div>
</div>
your plunker has a very minor issue.
change this
angular.module('myApp', [])
to
angular.module('myApp', ['myNewApp'])
I have a controller as main controller and a its child controller. I want to execute first the main controller and then after its child controller.
I am collecting some userdata and want to keep it in $rootScope so that i could access it within the whole application.
How could i do this ?
<body ng-app="angularApp">
<div ng-controller="MainAppController">
<div ng-controller="childController">
Here i want to access data from "MainAppController" stored in $rootScope
But problem is "childController" runs before "MainAppController"
</div>
</div>
</body>
Here is the angular code
angular.module('MyApp').controller('MainAppController', function($rootScope, service){
$rootScope.userData = [];
service.getUserData().success(function(userDetails){
$rootScope.userData = userDetails;
});
});
angular.module('MyApp').controller('childController', function($scope, $rootScope){
$scope.userInfo = $rootScope.userData;
//Here $scope.userInfo is null because $rootScope.userData gets assigned to $scope.userInfo in this controller before userDetails gets assigned to $rootScope.userData in MainAppController controller.
I want that untill "$rootScope.userData = userDetails;" is not finished , "$scope.userInfo = $rootScope.userData;" must not run.
How can i do this ?
});
There are two ways i know you can do this.
1 way ::
Use $rootScope.userData directly in html and when your parent controller will run $rootScope.userData will get updated and by dual binding feature of angular, your view will get updated accordingly
Code::
//angularjs Code
var app = angular.module('MyApp', []);
app.controller('MainController', function($rootScope, $timeout) {
$rootScope.userData = {};
$timeout(function() {
$rootScope.userData = {name:'myName'};
}, 3000);
});
app.controller('childController', function() {
});
//html code
<div ng-app="MyApp" ng-controller="MainController">
<div ng-controller="childController">
{{userData.name}}
</div>
</div>
2 way::
You can attach $watch on $rootScope.userData in childController so when $rootScope.userData will get updated $watch will run and inside $watch you can update your $scope variable
Code::
//Angularjs Code
var app = angular.module('MyApp', []);
app.controller('MainController', function($rootScope, $timeout) {
$rootScope.userData = {};
$timeout(function() {
$rootScope.userData = {name:'myName'};
}, 2000);
});
app.controller('childController', function($scope, $rootScope) {
$scope.$watch(function(){
return $rootScope.userData;
}, function(){
$scope.userInfo = $rootScope.userData;
});
});
//HTML Code
<div ng-app="MyApp" ng-controller="MainController">
<div ng-controller="childController">
{{userInfo.name}}
</div>
</div>