$emit + $on / $broadcast + $on are not working in AngularJS - angularjs

I need to call function in another controller in AngularJS. How it is possible? I used below code but it's not working.
EmployeeCtrl
routerApp.controller('EmployeeController', function ($scope, $rootScope) {
$rootScope.$on("CallSearchtMethod", function (searchName) {
$scope.parentmethod(searchName);
});
$scope.parentmethod = function (searchName) {
console.log("data is" + searchName);
}
}
})
NavCtrl
routerApp.controller('navCtrl', function ($scope,$rootScope ) {
$scope.searchFun = function (searchName) {
$rootScope.$emit("CallSearchtMethod", searchName);
}
})

You should use Service. What it does is that it allows you to create common functions that will be used in many places, which in this case are controllers.
Here is an example working code snippet that will guide you to do the Service.
angular.module('starterByAR', ['starterByAR.controllers', 'starterByAR.services']);
angular.module('starterByAR.controllers', [])
.controller('mainOne', [
'$scope', 'myService',
function($scope, myService) {
$scope.text = myService.commonFunction();
}
])
.controller('mainTwo', [
'$scope', 'myService',
function($scope, myService) {
$scope.text = myService.commonFunction();
}
]);
angular.module('starterByAR.services', []).service('myService', function() {
return {
commonFunction: function(){
return 'Some Text';
}
};
});
<head>
<title>Angular Starter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<body ng-app="starterByAR">
<div ng-controller="mainOne">
Here is {{text}} from Controller 1
</div>
<div ng-controller="mainTwo">
Here is {{text}} from Controller 2
</div>
</body>

Related

Fire $emit event if model property change

I'm trying to pass some data from child controller to parent controller using $emit + $on .
Here is my code.
angular.module('myApp', [])
.controller('parentCtrl', ['$scope', '$http', '$q', function ($scope, $http, $q) {
$scope.message = 'parent';
$scope.$on('EventFromChild', function (event, data) {
console.log("Event Received");
$scope.message = data;
});
}])
.controller('childCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.data ={"name":"Amit","lastname":"kumar"};
$scope.$emit('EventFromChild',$scope.data.name);
$scope.update = function(){
console.log("Clicked");
$scope.data.name ="Testing";
};
}]);
When page is loaded then, Then it successfully passes the data from the child to parent, But when I update the data in child then I also want it to get reflected in parent controller, But it is not emitting the event.
Plunker
It is because you are doing nothing when the child is updated.
You have to use $watch for observing changes. For example, if you want emit changes when data.name changes:
$scope.$watch('data.name', function() {
$scope.$emit('EventFromChild',$scope.data.name);
});
Or when any property of data changes:
$scope.$watch('data', function() {
$scope.$emit('EventFromChild',$scope.data);
});
This way the come becomes:
angular.module('app.controllers', [])
.controller('parentCtrl', ['$scope', '$http', '$q', function ($scope, $http, $q) {
$scope.message = 'parent';
$scope.$on('EventFromChild', function (event, data) {
console.log("Event Received");
$scope.message = data;
});
}])
.controller('childCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.data ={"name":"Amit","lastname":"kumar"};
$scope.$emit('EventFromChild',$scope.data.name);
$scope.update = function(){
console.log("Clicked");
$scope.data.name ="Testing";
};
$scope.$watch('data.name', function() {
$scope.$emit('EventFromChild', $scope.data.name);
});
}]);
Snippet:
// Code goes here
mc = angular.module('app', [
'app.controllers',
]);
angular.module('app.controllers', [])
.controller('parentCtrl', ['$scope', '$http', '$q', function ($scope, $http, $q) {
$scope.message = 'parent';
$scope.$on('EventFromChild', function (event, data) {
console.log("Event Received");
$scope.message = data;
});
}])
.controller('childCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.data ={"name":"Amit","lastname":"kumar"};
$scope.update = function(){
console.log("Clicked");
$scope.data.name ="Testing";
};
$scope.$watch('data.name', function() {
$scope.$emit('EventFromChild',$scope.data.name);
});
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>
<div ng-app="app" ng-controller="parentCtrl">
<b>Parent Event:</b> {{message}}<br />
<br/><br/>
<div ng-controller="childCtrl">
<b>Child Event:</b> {{data.name}}<br />
<input type="button" ng-click="update()" value ="update"/>
</div>
</div>

ng-repeat through an Array of Objects

I'm creating a little shoutbox with angular JS and StamPlay. Therefore I've created some 'Test Shouts' than can be accesed via an URL
In my Angular app I've created a Service to fetch the data:
app.factory('shouts', ['$http', function ($http) {
return $http.get('https://shoutbox.stamplayapp.com/api/cobject/v1/shouts').success(function (data) {
return data.data;
});
}]);
Inside my MainController I attach the data to the $scope.
app.controller('HomeController', [
'$scope',
'shouts',
function ($scope, shouts) {
$scope.shouts = shouts;
}
]);
But when I'm tyring to ng-repeat through the data[], i can't access the objects inside. I don't understand whats the problem.
<div ng-repeat="shout in shouts">
{{shout.title}}
</div>
shouts is a $promise even you do "return data.data". So you need to assign $scope.shouts when the promise resolved.
app.factory('shouts', ['$http', function ($http) {
return $http.get('https://shoutbox.stamplayapp.com/api/cobject/v1/shouts');
}]);
app.controller('HomeController', [
'$scope',
'shouts',
function ($scope, shouts) {
shouts.then(function(data) { $scope.shouts = data.data});
}
]);
Another options is to resolve shouts in you route config and inject it into the controller
$routeProvider
.when("/home", {
templateUrl: "home.html",
controller: "HomeController",
resolve: {
shout_data: shouts
}
app.controller('HomeController', [
'$scope',
'shout_data',
function ($scope, shout_data) {
$scope.shouts = shout_data;
}
]);
Did you forget to attach your controller to the HTML?
<div ng-controller="HomeController">
<div ng-repeat="shout in shouts">
{{shout.title}}
</div>
</div>
More information about ngController: https://docs.angularjs.org/api/ng/directive/ngController

How to redirect to an external URL

When trying to redirect to an external page using $window.location.href, the page is just refreshing and not redirecting to the expected URL.
<html ng-app="myApp">
<head>
</head>
<body ng-controller="myCtrl">
<p> <button>Click me to redirect from template</button></p>
<p ng-click="myFunction()"> <button>Click me to redirect from controller</button></p>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var app = angular.module('myApp',[]);
app.controller('myCtrl',function($window,$scope){
$scope.myFunction = function(){
$window.location.href = 'http://www.google.com'; //You should have http here.
}
});
</script>
</body>
</html>
This works for me.
pdmApp.controller('projectionDetailController', [ '$log', 'projectionDetailService', '$filter', '$window', '$location', '$scope', function ($log, pdService, $filter,$window,$location, $scope) {
$scope.backToPreviousPage = function () {
alert("function is working"); //Add this line to your code to confirm your function is called.
$window.location.href = "http://localhost:port/../sample2.aspx";
}
} //What is this bracket for?
}]); //you are missing this square bracket.
Change To
pdmApp.controller('projectionDetailController', ['$log', 'projectionDetailService', '$filter', '$window', '$location', '$scope', function($log, pdService, $filter, $window, $location, $scope) {
$scope.backToPreviousPage = function() {
alert("function is working"); //Add this line to your code to confirm your function is called.
$window.location.href = "http://localhost:port/../sample2.aspx";
};
]);

How to communicate between controllers of two different modules in AngularJs

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'])

Angular $broadcast not working.

I am trying to share informations between two controllers with $scope.$on and $scope.$broadcast.
Here is the view:
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
{{content}}
</div>
</div>
and the controllers:
.controller('ParentCtrl', ['$scope', function($scope) {
$scope.$broadcast('someEvent', 'bidule');
}])
.controller('ChildCtrl', ['$scope', function($scope) {
$scope.$on('someEvent', function(event, b) {
$scope.content = b;
});
}])
and the plunker
What am I doing wrong here?
The child controller isn't instantiated yet. Wrapping the broadcast in a timeout works:
http://plnkr.co/edit/MF7P16K1OTv46JNgkkih?p=preview
$timeout(function(){
$scope.$broadcast('someEvent', 'bidule');
});
Child not initiated. Faced the same issue and this was my solution.
.controller('ParentCtrl', ['$scope', function($scope) {
$scope.$on('initiateEvent', function(event, b) {
$scope.$broadcast('someEvent', 'bidule');
}
}])
.controller('ChildCtrl', ['$scope', function($scope) {
$scope.$on('someEvent', function(event, b) {
$scope.content = b;
});
$scope.$emit('initiateEvent', null);
}])
Here i'm initiating the child and asking the parent to broadcast someEvent
To broadcast an event, you simply have to call it.
The following code works perfectly :
Your view :
<div ng-controller="ParentCtrl" ng-click="myFunc()">
<div ng-controller="ChildCtrl">
{{content}}
</div>
</div>
and your controllers :
.controller('ParentCtrl', ['$scope', function($scope) {
$scope.myFunc = function() {
$scope.$broadcast('someEvent', 'bidule');
}
}])
.controller('ChildCtrl', ['$scope', function($scope) {
$scope.$on('someEvent', function(event, b) {
$scope.content = b;
});
}])
Hope it helps !

Resources