Is it legal for a controller to do something like this in Angular?
$rootScope.someArbitaryObject = ["fee", "fie", "fo", "fum];
or
$rootScope.foo = {name: "Jane Q. Public", favoriteColor: "green"}
Yes, it is legal but only if you want ALL controllers to have access to that model.
A better practice is to use services that you can then inject to one or more controllers:
var myApp = angular.module('myApp', []);
myApp.factory('MyService', function () {
return { message: "I'm data from a service" };
});
myApp.controller('FirstCtrl', function($scope, MyService) {
$scope.data = MyService;
});
myApp.controller('SecondCtrl', function($scope, MyService) {
$scope.data = MyService;
});
Any change you make to MyService properties in one controller will affect all the other controllers that use MyService.
regarding the question in your comments, a good way to share date is through localstorage (or sessionStorage). I wrote a storageService which allows you to save, load and delete.
angular.module(yourApplication).service('storageService', [
function() {
// implementation using localStorage. Future possibility to user $cookie service here, or sessionStorage, depends on what you want
return {
save: function(key, jsonData, expirationMin){ // default is 30 minute expiration
if(!expirationMin)
expirationMin = 30;
var expirationMS = expirationMin * 60 * 1000;
var record = {
value: JSON.stringify(jsonData),
timestamp: new Date().getTime() + expirationMS
};
localStorage.setItem(key, JSON.stringify(record));
return jsonData;
},
load: function(key){
var record = JSON.parse(localStorage.getItem(key));
if (!record){
return false;
}
return (new Date().getTime() < record.timestamp && JSON.parse(record.value));
},
remove: function(key){
localStorage.removeItem(key);
}
};
}
]);
Another way using services (Modified Yoni's code a little):
var myApp = angular.module('myApp', []);
myApp.service('MyService', function () {
var someData = 'test';
return {
getData: function(){ return someData},
setData: function(input){ someData = input;}
};
});
myApp.controller('FirstCtrl', function($scope, MyService) {
$scope.data = MyService.getData();
});
myApp.controller('SecondCtrl', function($scope, MyService) {
$scope.data = MyService.getData;
});
Related
/*service */
app.service('sharedProperties', function () {
var property = 'First';
return {
getProperty: function () {
return property;
},
setProperty: function(value) {
property = value;
}
};
});
/*first contoller */
app.controller('loginCtrl',function($scope,$location,$http,$window,sharedProperties){
$scope.submit =function(){
var username=$scope.username;
var pass=$scope.password;
sharedProperties.setProperty(username);
$location.path('/userdashboard');
$window.location.reload();
});
}
});
/*second controller*/
app.controller('empController', function($route,$scope,$http,$routeParams,sharedProperties){
$scope.getEmployees = function(){
alert( sharedProperties.getProperty());
};
};
Try this, it will work for you. :
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="sendData();"></button>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
function sendData($scope) {
var arrayData = [1,2,3];
$scope.$emit('someEvent', arrayData);
}
});
app.controller('yourCtrl', function($scope, $http) {
$scope.$on('someEvent', function(event, data) {
console.log(data);
});
});
</script>
Service does not need to return anything. You have to assign everything in this variable. Because service will create instance by default and use that as a base object.
app.service('sharedProperties', function () {
this.property = 'First';
});
Then in controller
sharedProperties.property = $scope.username;
Had you been looking to use factory
app.factory('sharedProperties', function () {
var factory = {};
factory.property = 'Hello';
factory.setProperty = function (value) {
factory.property = value;
};
return factory;
});
Then in controller you would use it
sharedProperties.setProperty($scope.username); // Setter
$scope.var = sharedProperties.property; //getter
EDIT
Working Plnkr
You can assign members to $rootScope, which will store data globally for your app. Just inject $rootScope to each controller.
For instance...
/*first controller */
app.controller('loginCtrl',function($scope,$rootScope,$location,$http,$window,sharedProperties){
$scope.submit =function(){
var username=$scope.username;
var pass=$scope.password;
$rootScope.username = username;
$location.path('/userdashboard');
$window.location.reload();
});
}
});
This will make 'username' available to any controller that injects and consumes $rootScope.
/*second controller*/
app.controller('empController', function($route,$scope,$rootScope,$http,$routeParams,sharedProperties){
$scope.getEmployees = function(){
alert($rootScope.username);
};
};
I have a module with a service defined:
var ngError = angular.module('ngError', []);
ngError.service('ErrorService', ['$scope', function($scope) {
$scope.displayErrors = function(errors) {
alert(errors);
}
}]);
Then I have another module:
var ngLogin = angular.module('ngLogin', ['ngError']);
Which has a controller that attempts to use the first service defined on ngError:
ngLogin.controller('LoginCtrl', ['$scope', 'LoginService', 'ErrorService', function($scope, LoginService, ErrorService) {
$scope.user = {};
$scope.user.id = 0;
$scope.user.token = '';
$scope.login = function(callback) {
LoginService.login($scope.user.username, $scope.user.password, function(token) {
$scope.setToken(token);
$scope.$apply();
if (typeof callback === 'function') {
callback(callback);
}
}, function(errors) {
ErrorService.displayErrors(errors);
});
};
}]);
But some reason this is throwing the following error:
Unknown provider: $scopeProvider <- $scope <- ErrorService
You cannot use $scope within a service. Change the service as follows and it will work:
var ngError = angular.module('ngError', []);
ngError.service('ErrorService', [function() {
this.displayErrors = function(errors) {
alert(errors);
}
}]);
Try like this , working best for me
var app = angular.module('MyApp', []);
app.service('MyService', function () {
var property = 'First';
this.myFunc = function (x) {
return x*5;
}
});
//
controller 2 under second app module
var app = angular.module('AnotherApp',[]);
app.controller("AnotherAppCtrl", function($scope,MyService) {
$scope.value = MyService.myFunc(4);
});
I'm very new to AngularJS, how can I pass input scope from first controller to the second controller for the data $scope.requestURL
I've search about the service method but I have no idea how to apply it.
.controller('ZipController', ['$scope', function($scope) {
$scope.zipCode = '10028';
$scope.setURL = function() {
$scope.requestURL = 'http://congress.api.sunlightfoundation.com/legislators/locate?zip=' + $scope.zipCode + '&apikey=xxxxx';
};
}])
.controller('ListController', ['$scope', '$http',
function($scope, $http) {
$http.get($scope.requestURL).success(function(data) {
console.log(data.results);
$scope.congress = data.results;
});
}]);
Here is a quick solution: ..you don't have to use the $http core service for your case:
You can also read more about angular's constant service..
(function(angular) {
var app = angular.module('myServiceModule', []);
app.controller('ZipController', function($scope, myService) {
$scope.zipCode = '10028';
myService.setFunc($scope.zipCode);
myService.zipCode = $scope.zipCode;
});
app.controller('ListController', function($scope, myService) {
$scope.requestURL = myService.getFunc();
});
app.factory('myService', function() {
var zipCode;
var setFunc = function(zip) {
zipCode = zip;
};
var getFunc = function() {
return 'http://congress.api.sunlightfoundation.com/legislators/locate?zip=' + zipCode + '&apikey=xxxxx'
};
return {
zipCode: zipCode,
setFunc: setFunc,
getFunc: getFunc
};
});
})(window.angular);
Try setting it to $rootScope.requestURL and access it from the second controller.
I'm an angular newbie and I'm writing an Ionic app.
I finished my app and am trying to refactor my controller avoiding code repetition.
I have this piece of code that manages my modal:
angular.module('starter')
.controller('NewsCtrl', function($scope, content, $cordovaSocialSharing, $timeout, $sce, $ionicModal){
$scope.news = content;
content.getList('comments').then(function (comments) {
$scope.comments = comments;
});
$scope.addComment = function() {
};
$scope.shareAnywhere = function() {
$cordovaSocialSharing.share("Guarda questo articolo pubblicato da DDay", "Ti stanno segnalando questo articolo", content.thumbnail, "http://blog.nraboy.com");
};
$ionicModal.fromTemplateUrl('templates/comments.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.showComment = function() {
$scope.modal.show();
};
// Triggered in the login modal to close it
$scope.closeComment = function() {
$scope.modal.hide();
};
$scope.$on('modal.shown', function() {
var footerBar;
var scroller;
var txtInput;
$timeout(function() {
footerBar = document.body.querySelector('#commentView .bar-footer');
scroller = document.body.querySelector('#commentView .scroll-content');
txtInput = angular.element(footerBar.querySelector('textarea'));
}, 0);
$scope.$on('taResize', function(e, ta) {
if (!ta) return;
var taHeight = ta[0].offsetHeight;
if (!footerBar) return;
var newFooterHeight = taHeight + 10;
newFooterHeight = (newFooterHeight > 44) ? newFooterHeight : 44;
footerBar.style.height = newFooterHeight + 'px';
scroller.style.bottom = newFooterHeight + 'px';
});
});
});
I have added this same code in 6 controllers.
Is there a way to avoid the repetition?
Probably what you are looking for is an angular service. This component is a singleton object, that you inject in every controller you need to execute this code.
Angular Services
Regards,
Below is an example of a service I created to retrieve address data from a Json file. Here is the working Plunk. http://plnkr.co/edit/RRPv2p4ryQgDEcFqRHHz?p=preview
angular.module('myApp')
.factory('addressService', addressService);
addressService.$inject = ['$q', '$timeout', '$http'];
function addressService($q, $timeout, $http) {
var addresses = [];
//console.log("Number of table entries is: " + orders.length);
var promise = $http.get('address.data.json');
promise.then(function(response) {
addresses = response.data;
// console.log("Number of table entries is now: " + orders.length);
});
return {
GetAddresses: getAddresses
};
function getAddresses() {
return $q(function(resolve, reject) {
$timeout(function() {
resolve(addresses);
}, 2000);
});
}
}
Here's an example of how I added dependencies for it and another service to my controller (This is NOT the only way to do dependency injection, but is my favorite way as it is easier to read). I then called my addressService.GetAddresses() from within my controller.
var app = angular.module('myApp', ['smart-table']);
app.controller('TableController', TableController);
TableController.$inject = [ "orderService", "addressService"];
function TableController( orderService, addressService) {
addressService.GetAddresses()
.then(function(results) {
me.addresses = results;
// console.log(me.addresses.length + " addresses");
},
function(error) {})
.finally(function() {
me.loadingAddresses = false;
});
});}
I also had to include my .js tag in a script element on my index.html.
<script src="addressdata.service.js"></script>
Question is simple, i have value in a controller, and i want to send this value to another controller.
I have this code :
var app = angular.module("MyApp", []);
app.factory("UserService", function() {
var users = //how to get the value user of MyCtrl ?
return {
all: function() {
return users;
},
first: function() {
return users[0];
}
};
});
app.controller("MyCtrl", function($scope, UserService) {
var users = ["Peter", "Daniel", "Nina"];
$scope.users = UserService.all();
});
app.controller("AnotherCtrl", function($scope, UserService) {
$scope.firstUser = UserService.first();
});
I didn't know how to get value of var users = ["Peter", "Daniel", "Nina"]; from the controller MyCtrl in UserService ?
live exemple :http://jsbin.com/vacutodo/1/edit?html,js,output
You can inject it into your function:
app.factory('UserService', ['MyCtrl', function(MyCtrl) {
var users = MyCtrl.users;
...
};
app.controller("MyCtrl", function($scope, UserService) {
var users = ["Peter", "Daniel", "Nina"];
$scope.users = UserService.all();
return {
users: users
};
});