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>
Related
In the example below, how can I run getData from another controller and have the scope variable in the view updated?
var app = angular.module('app', []);
app.factory('MyService', ['$http',function($http) {
return {
getData: function() {
return $http.get('/api/endpoint');
}
};
}]);
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.getData().then(function(response){
$scope.myVarialbe = response.data;
});
}]);
app.controller('MyController2', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
///// ?????? How to get $scope.myVarialbe updated from the getData call?
});
}]);
Using $broadcast and $on :
$broadcast dispatches an event name downwards to all child scopes (and their children) and notify to the registered $Scope listeners. The event life cycle starts at the scope on which $broadcast was called. All listeners for the event on this scope get notified.
$on listen on events of a given type. It can catch the event dispatched by $broadcast
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
$scope.$on('variableChanged',function(event, value) {
$scope.myVariable = value;
};
}]);
app.controller('MyController2', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.getData().then(function(response){
$scope.$broadcast('variableChanged', response.data);
});
}]);
angular.module('app').controller('nav', function($scope,$http) {
$rootScope.$on("CallMethodNavController", function(){
$scope.navMethod();
});
$scope.navMethod=function(){
$http.get('/players').then(function(data) {
$scope.numOfPlayers = data.players.length;
}
});
});
then in the second controller you call this method once a player is added like so:
$rootScope.$emit("CallMethodNavController", {});
I have an angular app with the name DemoProject.
I have an app.run controller and one child controller
JS
var app = angular.module("DemoProject", ['ngRoute', 'ngAnimate', 'ngMessages', 'ngMaterial']);
app.run(function ($rootScope, $route, $location, $mdDialog) {
$rootScope.validate = true;
$rootScope.$broadcast('eventName', { myName: 'Bala' });
});
app.controller('ChildController', function ($scope, $location, $rootScope, $document, $window) {
$scope.myName = '';
});
I can't update the child controller scope using broadcast.
app.controller('ChildController', function ($scope, $location, $rootScope, $document, $window) {
$scope.myName = '';
$rootScope.$on('eventName', function(event, args){
console.log(args);
$scope.myName = args.myName;
});
});
I already have a code with 2 separate controllers .
Each controller's scope/view has an input text and a span.
All fine.
But Looking at the line with yellow color label(empty at the moment) - which is found within the second controller , I want the value to be the same value from as in first controller .
so I'm expecting the line to be (and changed automatically) :
Value from the FirstController is :First Cntrl
I already know that I need a serivce :
so here is my code :
angular.module('app', [])
.controller("FirstCtrl", ['$rootScope', '$scope', 'myservice', function($rootScope, $scope, myservice)
{
myservice.messageFromCntrl1= this.message;
this.message = "First Cntrl";
}]).controller("SecondCtrl", ['$rootScope', '$scope', 'myservice', function($rootScope, $scope, myservice)
{
this.message = "Second Cntrl";
this.messageFromCntrl1 = myservice.messageFromCntrl1;
}])
.service('myservice', function()
{
this.messageFromCntrl1 = "???";
});
In the first controller I do set
myservice.messageFromCntrl1= this.message;
And in the second controller I do read :
this.messageFromCntrl1 = myservice.messageFromCntrl1;
And in the HTML :
Value from the FirstController is :<span style='color:red;'>{{myservice.messageFromCntrl1}}
But it doesn't work. What am I missing?
JSBIN
I modified your JSBIN, check it here. I believe it behaves now as you want it to.
angular.module('app', [])
.controller("FirstCtrl", ['$rootScope', '$scope', 'myservice', function($rootScope, $scope, myservice)
{
this.message = myservice.messageFromCntrl1;
this.message.data = "First Cntrl";
}]).controller("SecondCtrl", ['$rootScope', '$scope', 'myservice', function($rootScope, $scope, myservice)
{
this.message = "Second Cntrl";
this.messageFromCntrl1 = myservice.messageFromCntrl1;
}])
.service('myservice', function()
{
this.messageFromCntrl1 = {data:""};
});
And in your view
<div ng-controller="FirstCtrl as first">
<input type="text" ng-model="first.message.data">
<h1>{{first.message.data}}</h1>
</div>
<div ng-controller="SecondCtrl as second">
<input type="text" ng-model="second.message">
<h1>{{second.message}} </h1>
Value from the FirstController is:
<span style='color:red;'>{{second.messageFromCntrl1.data}}</span>
</div>
First of all, if you want to keep this value updated between controllers you need to use objects and not simple variables. With objects you operate on references and updates are shared between all references of object.
Second, you tried to access service directly in view. You need to bind service reference to controller's scope.
I've made an edit to your jsbin, tell me if that's what you need
https://jsbin.com/mapuwojocu/1/edit?html,js,output
angular.module('app', [])
.controller("FirstCtrl", ['$rootScope', '$scope', 'myservice',
function ($rootScope, $scope, myservice) {
this.message = "First Cntrl";
this.myservice = myservice;
}
]).controller("SecondCtrl", ['$rootScope', '$scope', 'myservice',
function ($rootScope, $scope, myservice) {
this.message = "Second Cntrl";
this.myservice = myservice;
}
])
.service('myservice', function () {
return {
message: 'Cntrl'
};
});
You can't access service through the view. In addition change all your this to $scope in your controller.
Look at this example:
angular.module('app1', [])
.controller("FirstCtrl", ['$scope', 'myservice', function($scope, myservice)
{
$scope.message = "First Cntrl from code";
myservice.messageFromCntrl1= $scope.message;
}])
.controller("SecondCtrl", ['$scope', 'myservice', function($scope, myservice)
{
$scope.message = "Second Cntrl Code";
$scope.messageFromCntrl1 = myservice.messageFromCntrl1;
}])
.service('myservice', function()
{
this.messageFromCntrl1 = "???";
});
The issue is that I can't seem to send information from Controller 1 to Controller 2... I have my service that sets/gets data but it isn't working. The actual error that I'm getting is that Controller 1's dataService.getData is not a function... when it works elsewhere.
Service 1 (in its own file)
app.service('dataService', function() {
var data, queried;
return {
setData: function(queryData) {
this.data = queryData;
this.queried = false;
},
getData: function() {
this.queried = true;
return this.data;
}
};
});
Controller 1 (sending information)
app.controller('MyCtrl', ['$scope', '$location', '$state', function($scope, $location, $state, dataService) {
anotherService.functionName(function(err, data) {
// do some things here
actualService.doesntWork(function(err, data) {
if (!err) {
var query = {};
query.someField = data.someField;
dataService.setData(query);
$state.go("go.somewhere.else");
}
});
});
}]);
Controller 2 (getting information)
app.controller('MyCtrl2', ['$scope', '$location', '$state', function($scope, $location, $state, dataService) {
$scope.buttonPressed = function() {
console.log(dataService.getData());
}
}]);
You didn't injected service dataService inside your MyCtrl & MyCtrl2, ensure dependency should be injected before using it.
Controller
app.controller('MyCtrl', ['$scope', '$location', '$state','dataService', //<-added dependency here
function($scope, $location, $state, dataService) {
anotherService.functionName(function(err, data) {
// do some things here
actualService.doesntWork(function(err, data) {
if (!err) {
var query = {};
query.someField = data.someField;
dataService.setData(query);
$state.go("go.somewhere.else");
}
});
});
}]);
Controller2
app.controller('MyCtrl2', ['$scope', '$location', '$state','dataService',//<-added dependency here
function($scope, $location, $state, dataService) {
$scope.buttonPressed = function() {
console.log(dataService.getData());
}
}]);
I want to get $scope variable value from "inherited" controller. It works for non-scope var but for scope var prints undefined.
appControllers.controller('parentCtrl', ['$scope', '$rootScope', '$http', '$location', '$log',
function ($scope, $rootScope, $http, $location, $log) {
$scope.someVariable = "Scope hello world.";
$scope.getLocalVariable = function (){
return "hello world";
}
$scope.getScopeVariable = function (){
return $scope.someVariable;
}
}]);
appControllers.controller('childCtrl', ['$scope', '$rootScope', '$http', '$location', '$log',
function ($scope, $rootScope, $http, $location, $log) {
$log.debug($scope.getLocalVariable()); // this WORKS
$log.debug($scope.getScopeVariable()); // this DOES NOT WORKS - prints undefined
}]);
part of .html file
<div ng-controller="parentCtrl">
<div ng-controller="childCtrl">
</div>
</div>
Do you have any idea? I also tried
var app = angular.module('angularjs-starter', []);
app.controller('ParentCtrl ', function($scope) {
// I'm the sibling, but want to act as parent
});
app.controller('ChildCtrl', function($scope, $controller) {
var ctrl = $controller('ParentCtrl', {$scope: $scope});
ctrl.methodCall() // DOES NOT WORK
});
But it did not helped. Thanks