I am trying to write some very primitive angular code with 2 controllers and 1 service.
So when I call shared service from controller 1 and update data, I want to use same in my controller 2 $scope so that controller 2 $scope value can reflect on my DOM.
App.controller('oneCtrl', function($scope, $uibModal, $log, sharedProperties) {
// Call a new DOM element to so that ModalInstanceCtrl will be called
// Once controller 2 finishes, I want to update a $scope variable here
// $scope.projectList = getProjectList();
});
App.controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, sharedProperties) {
// This is a new modal which uses sharedProperties
// Update setProjectList() in service
});
App.service('sharedProperties', function() {
var projectList = new Array();
return {
getProjectList: function() {
return projectList;
},
setProjectList: function(value) {
projectList.push(value);
},
}
});
Once controller 2 calls setProjectList(). I want to auto update $scope value in controller 1 using getProjectList()
Please let me know how I can do that? Also do let me know if any further details needed on same.
A service in angular is a singleton so if you change data on the service it will be reflected whenever you call that service.
var app = angular.module('plunker', []);
app.controller('FirstCtrl', function($scope, userData) {
$scope.favoriteBook = userData.favoriteBook;
$scope.getFavoriteBook = function(){
$scope.favoriteBook = userData.favoriteBook;
}
});
app.controller('SecondCtrl', function($scope, userData) {
$scope.changeBook = function(){
userData.favoriteBook = 'The Hobbyt';
}
});
app.factory('userData', function(){
var favoriteBook = 'Harry Potter';
return{
favoriteBook : favoriteBook
}
})
Here you got a service that exposes an object, you can change the value of that object in the second controller and see it reflected in the first controller. Call changeBook(), and then getFavoriteBook()
This is the plunker:
the plunker
Related
I have my notification listener in the run function. When a notification is received I need to update a object present in $scope with a parameter present in notification object.
angular.module('app', ['ionic', 'chatsCtrl'])
.run(function($state, $ionicPlatform) {
window.FirebasePlugin.onNotificationOpen(function(notification) {
// Need to append this notification.parameter to a scope variable present in a controller
}
}
.controller('chatsCtrl', function($scope) {
// $scope.chats
});
How can I go about doing this? I don't want to use $rootScope object as $scope.chat object will get very heavy.
Thanks
you can't call scope variables/functions inside run block. since you don't want to use rootscope my suggestion is to create a service and assign values to a particular method in that service from the run block. Then get that value from the controller using the same service.
angular.module('app', ['ionic', 'chatsCtrl'])
.run(function($state, $ionicPlatform) {
window.FirebasePlugin.onNotificationOpen(function(notification) {
sampleService.setData(notification)
}
}
.controller('chatsCtrl', function($scope,sampleService) {
$scope.chats = sampleService.getData()
});
.factory('sampleService', function() {
var data;
return {
getData : function(){ return data},
setData: function(param){ data = param},
}
});
I have two controllers. The view is tied to the firstCtrl. I'm trying to run the function in the second one so the view is updated. Function runs but view not updated. Any ideas?
<div>{{people.length}}</div>
angular.module('myApp').controller('firstCtrl', function($scope, $http) {
var self = this;
$scope.people = [];
function getData() {
$http.get('/people').then(function(res) {
$scope.people = res.data;
});
}
getData();
$scope.getData = getData;
self.getData = function(){
$scope.getData();
};
return self;
});
angular.module('myApp').controller('secondCtrl', function( $controller, $scope, $http) {
var firstCtrl= $controller('firstCtrl', { $scope: $scope.$new() });
firstCtrl.getData(); //This runs but view is not updated above.
});
I think your code has some problem with the $scope. So instead of pass data directly in the firstCtrl. I pass a callback to getData function and assign data to $scope.people in the callback.
Here is the working Plunker:
> http://plnkr.co/edit/QznxFL
I have two controller Controller A and controller B . controller A has an object $scope.operation={}; which is a json containing details.
In controller B I want to compare the detail of this json object and then run a function in COntroller B .How to achieve this..Thanks
Use a factory/service to store the operations array, whenever the value changes in the ControllerA controller update the values in service.
myApp.factory('myService', [function() {
var operations = {};
return {
getOperations: function() {
return operations
},
setOperations: function(op) {
operations = op;
},
}
}])
.controller('ControllerA', [function($scope, myService) {
$scope.operations = {};
$scope.$watch(function() {
return $scope.operations;
}, function() {
myService.setOperations($scope.operations);
});
}])
.controller('ControllerB', [function($scope, myService) {
$scope.operations = myService.getOperations();
}]);
I have two controllers- searchBoxController and productList. What I am trying to do is to update the scope variable $scope.products from multiple controllers. I know that defining it as a root variable is a very bad design- but putting that in shared service is not solving the problem. The update doesn't reflect in the HTML templates!
function SearchTermService(){
this.productSearch = function(data, $http){
var url = "";
$http.get(url).then(function(resp){
return resp.data;
},
function(err){
console.log(err);
});
};
};
var app = angular.module('app', []);
app.service("myService", MyService);
app.service("searchTermService", SearchTermService);
app.run(function($rootScope) {
$rootScope.products = new Date();
});
app.controller('productList', function ($scope, $rootScope, $http, myService) {
$rootScope.products = prod_res;
});
app.controller('searchBoxController', function($scope, $http, searchTermService, $rootScope){
$scope.getSearchResults = function(){
$rootScope.products = searchTermService.productSearch($scope.term, $http)
};
});
PS: I am not sure if I need to have a promise returned while assigning the $rootScope.products in 'searchBoxController', as the console.log says its undefined. Currently I am not returning a promise from the service.
In order to update a scope variable across multiple controller, you can use angular service.
You should use this because all angular services are singletons, so you can easily share common logic, share data between controller.
I've made an example where I use service in order to update some data. Then, my factory return an object data, so we will get an object, not just a fixed value. Thanks to this, our data will be updated, we will keep the binding data.
Controller
(function(){
function Controller($scope, $timeout, Service) {
//Retrieve current data object of our service
$scope.data = Service.value;
//will be set to 4
$timeout(function(){
Service.set(4, 'product');
}, 1000);
}
angular
.module('app', [])
.controller('ctrl', Controller);
})();
(function(){
function Controller2($scope, $timeout, Service) {
//Retrieve current data object of our service
$scope.data2 = Service.value;
}
angular
.module('app')
.controller('ctrl2', Controller2);
})();
Service
(function(){
function Service() {
//Our data object
var data = {
product: null
};
function set(value, field){
data[field] = value;
}
return {
set: set,
value: data
};
}
angular
.module('app')
.factory('Service', Service);
})();
HTML
<body ng-app='app'>
<div ng-controller='ctrl'>
<h2>Service value : {{data.product}}</h2>
</div>
<div ng-controller='ctrl2'>
<h2>Service value from controller2 : {{data2.product}}</h2>
</div>
</body>
So, we will share our data across multiple controller. By using services, you can avoid to use the $rootScope.
You can see the Working plunker
I have two controllers that are active on my page:
// For handling any changes made to the Recipe Window
ctrl.controller('recipeCtrl', ['$scope', 'view_service', 'recipe_service', function($scope, view_service, recipe_service) {
$scope.title = recipe_service.get_title();
}]);
ctrl.controller('setNameCtrl', ['$scope', 'view_service', 'recipe_service', function($scope, view_service, recipe_service) {
$scope.titleSet = recipe_service.get_title();
$scope.setName = function(){
recipe_service.set_title($scope.titleSet);
//view_service.set_view_url({url:"partials/typeWindow.tpl.html"});
};
}]);
Both controllers are pulling from this service:
serv.service('recipe_service', function(){
var recipe = {
title:"ace",
type:"",
market:[],
attribute:[]
};
return {
get_title: function() {
return recipe.title;
},
set_title: function(newTitle){
recipe.title = newTitle;
}
};
});
The second controller updates the "title" that the first controller is referencing. My problem is that once the second controller changes "title" in the service, the first controller is not updated to reflect the changes. What I am thinking that needs to happen is to some how refresh the first controller to pull in those new changes. Any suggestion on how to do so?
// For handling any changes made to the Recipe Window
ctrl.controller('recipeCtrl', ['$scope', 'view_service', 'recipe_service', function($scope, view_service, recipe_service) {
$scope.curRecipe = recipe_service.recipe;
}]);
ctrl.controller('setNameCtrl', ['$scope', 'view_service', 'recipe_service', function($scope, view_service, recipe_service) {
$scope.curRecipe = recipe_service.recipe;
$scope.setName = function(){
//view_service.set_view_url({url:"partials/typeWindow.tpl.html"});
};
}]);
serv.service('recipe_service', function(){
return {
recipe : {
title:"ace",
type:"",
market:[],
attribute:[]
},
set_title: function(newTitle){
recipe.title = newTitle;
}
};
});
Using the same object throughout will work... this object can be defined in the service or you can use
angular.module("myApp",[]).value("myObject","Shared Value");
then inject this into you controllers like
angular.module("myApp").controller("MyCtrl",function($scope,myObject){console.log(myObject)})
I also posted a plnkr a while back showing some of the options:
http://plnkr.co/edit/ABQsAxz1bNi34ehmPRsF?p=preview
Please find the below plunker
http://plnkr.co/edit/UQgAC8bzcJkmsfCMyP84?p=preview