How to pass a global value in angularjs? - angularjs

I am building an angularjs based web app. I have included the ajax loader in the header. I have implemented bootstrap modals for login and signup. Each modal have its own controller. I didn't able to get ajax loader on and off values in the header. I want to implement some kind of Global value, which can be accessed throughout the ng-app scope.

using $rootScope you can achieve this :
set global variable in mainwindow :
function MyMainWindow($scope, $rootScope) {
$rootScope.name = 'Root Variable'; }
modal Window read global variable :
function MyModalWindow($scope, $rootScope) {
$scope.name2 = $rootScope.name; }
call root folder using {{name2}}
Hope this helps :)

You can assign a value to $rootScope, or you can make your value a property of an AngularJS factory/service.

You can add values to the $rootScope if you deed to with the following:
angular.module('myApp', [])
.run(function($rootScope) {
$rootScope.key = val;
});
But you should avoid using global variables as much as possible. Sometimes you need to use them but other times it is a symptom that your app could be built a different, better way. For this instance, you might create a directive that is applied to the header.

Related

What is the disadvantage of using the $scope as variable in angularjs, to share $scope of a controller inside the app.run?

What is the disadvantage of using the $scope as variable in AngularJS, to share $scope of a controller inside the app.run()?
Actually I am doing that to make code generic to be called from all the controllers with same function in app.run().
The function I am using is with the
$rootScope.getUserInfo = function($scope){
$scope.userinfo = '---------';
}
where $scope is the variable that I am passing from every controller like that
$rootScope.getUserInfo($scope);
I don't think there's inherently something wrong with passing around a scope. People do this a lot in AngularJS services and it's internally done a lot, too: your created controller is passed a scope to work with.
However, I would say it's not necessary in your example to have getUserInfo to depend on a scope being passed. Why not return the user information and have the caller put it on the scope? That way, you can use it in parts of your app that don't have a scope.
Instead of using $scope, you can use var vm = this; and define everything in that controller with vm.variablename_or_funcname instead of $scope.variablename_or_funcname
And you can attach that controller in html like ng-controller = "mycontroller as vm"
More info:
https://johnpapa.net/angularjss-controller-as-and-the-vm-variable/

Angularjs - get value from external DOM element

I am writing an angular application as module inside an existing application.
There is a hidden field in the outer application that I need.
My question is what is the best way to fetch this value and use it in my angular application?
Thanks.
Add your attribute in window object from anywhere in your code, use
<script>
window.my_value = 'value';
</script>
And in your controller, please inject $window service and then use
app.controller("MyController", function ($scope, $window) {
console.log($window.my_value);
})
OR
You can directly use this hidden field's value, like
var obj = angular.element(document.querySelector("#hiddenFieldId"));
console.log(obj.val());
If you have an ID/Class for that input..
You can always get the value with pure JS:
var input = document.getElementById('id');

Updating a view in AngularJS using $watch on a service

I'm a newbie to Angular and I'm struggling to understand how views are updated with scope changes. I am trying to update a header in my app using Angular JS based on whether a user is logged in. This information is returned by a Login service.
I have distilled my problem into two plunkers, one working and one not.
In order to get it to work I have to assign my LoginService to a variable on the scope of the HeaderCtrl.
angular.module('app', [])
.controller('HeaderCtrl', function ($scope, LoginService) {
$scope.loginService = LoginService;
$scope.$watch('loginService.isLoggedIn()', function(newVal) {
$scope.isLoggedIn = newVal;
});
Here is the working version
http://plnkr.co/edit/KBzE9N?p=preview
Now if I remove the reference to the LoginService in the scope of the HeaderCtrl and just use the injected service in the watch directly, the view stops updating. That is demonstrated here
http://plnkr.co/edit/IjFS2w?p=preview
Can anyone explain to me why the second case doesn't work? I've also read that it is a bad idea to have watches inside a controller so I'm open to better solutions.
Because the $watch watches scope variables in the scope you are calling it from. In your second example, $watch is looking for a LoginService variable in your scope, which of course does not exists.

Angular.js - share the same model between multiple views by $rootScope [duplicate]

I have a problem where i'm initialising a variable on the scope in a controller. Then it gets changed in another controller when a user logs in. This variable is used to control things such as the navigation bar and restricts access to parts of the site depending on the type of user, so its important that it holds its value. The problem with it is that the controller that initialises it, gets called again by angular some how and then resets the variable back to its initial value.
I assume this is not the correct way of declaring and initialising global variables, well its not really global, so my question is what is the correct way and is there any good examples around that work with the current version of angular?
You've got basically 2 options for "global" variables:
use a $rootScope http://docs.angularjs.org/api/ng.$rootScope
use a service http://docs.angularjs.org/guide/services
$rootScope is a parent of all scopes so values exposed there will be visible in all templates and controllers. Using the $rootScope is very easy as you can simply inject it into any controller and change values in this scope. It might be convenient but has all the problems of global variables.
Services are singletons that you can inject to any controller and expose their values in a controller's scope. Services, being singletons are still 'global' but you've got far better control over where those are used and exposed.
Using services is a bit more complex, but not that much, here is an example:
var myApp = angular.module('myApp',[]);
myApp.factory('UserService', function() {
return {
name : 'anonymous'
};
});
and then in a controller:
function MyCtrl($scope, UserService) {
$scope.name = UserService.name;
}
Here is the working jsFiddle: http://jsfiddle.net/pkozlowski_opensource/BRWPM/2/
If you just want to store a value, according to the Angular documentation on Providers, you should use the Value recipe:
var myApp = angular.module('myApp', []);
myApp.value('clientId', 'a12345654321x');
Then use it in a controller like this:
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
this.clientId = clientId;
}]);
The same thing can be achieved using a Provider, Factory, or Service since they are "just syntactic sugar on top of a provider recipe" but using Value will achieve what you want with minimal syntax.
The other option is to use $rootScope, but it's not really an option because you shouldn't use it for the same reasons you shouldn't use global variables in other languages. It's advised to be used sparingly.
Since all scopes inherit from $rootScope, if you have a variable $rootScope.data and someone forgets that data is already defined and creates $scope.data in a local scope you will run into problems.
If you want to modify this value and have it persist across all your controllers, use an object and modify the properties keeping in mind Javascript is pass by "copy of a reference":
myApp.value('clientId', { value: 'a12345654321x' });
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
this.clientId = clientId;
this.change = function(value) {
clientId.value = 'something else';
}
}];
JSFiddle example
Example of AngularJS "global variables" using $rootScope:
Controller 1 sets the global variable:
function MyCtrl1($scope, $rootScope) {
$rootScope.name = 'anonymous';
}
Controller 2 reads the global variable:
function MyCtrl2($scope, $rootScope) {
$scope.name2 = $rootScope.name;
}
Here is a working jsFiddle: http://jsfiddle.net/natefriedman/3XT3F/1/
In the interest of adding another idea to the wiki pool, but what about AngularJS' value and constant modules? I'm only just starting to use them myself, but it sounds to me like these are probably the best options here.
Note: as of the time of writing, Angular 1.3.7 is the latest stable, I believe these were added in 1.2.0, haven't confirmed this with the changelog though.
Depending on how many you need to define, you might want to create a separate file for them. But I generally define these just before my app's .config() block for easy access. Because these are still effectively modules, you'll need to rely on dependency injection to use them, but they are considered "global" to your app module.
For example:
angular.module('myApp', [])
.value('debug', true)
.constant('ENVIRONMENT', 'development')
.config({...})
Then inside any controller:
angular.module('myApp')
.controller('MainCtrl', function(debug, ENVIRONMENT), {
// here you can access `debug` and `ENVIRONMENT` as straight variables
})
From the initial question is actually sounds like static properties are required here anyway, either as mutable (value) or final (constant). It's more my personal opinion than anything else, but I find placing runtime configuration items on the $rootScope gets too messy, too quickly.
// app.js or break it up into seperate files
// whatever structure is your flavor
angular.module('myApp', [])
.constant('CONFIG', {
'APP_NAME' : 'My Awesome App',
'APP_VERSION' : '0.0.0',
'GOOGLE_ANALYTICS_ID' : '',
'BASE_URL' : '',
'SYSTEM_LANGUAGE' : ''
})
.controller('GlobalVarController', ['$scope', 'CONFIG', function($scope, CONFIG) {
// If you wish to show the CONFIG vars in the console:
console.log(CONFIG);
// And your CONFIG vars in .constant will be passed to the HTML doc with this:
$scope.config = CONFIG;
}]);
In your HTML:
<span ng-controller="GlobalVarController">{{config.APP_NAME}} | v{{config.APP_VERSION}}</span>
localStorage.username = 'blah'
If you're guaranteed to be on a modern browser. Though know your values will all be turned into strings.
Also has the handy benefit of being cached between reloads.
Please correct me if I'm wrong, but when Angular 2.0 is released I do not believe$rootScope will be around. My conjecture is based on the fact that $scope is being removed as well. Obviously controllers, will still exist, just not in the ng-controller fashion.Think of injecting controllers into directives instead. As the release comes imminent, it will be best to use services as global variables if you want an easier time to switch from verison 1.X to 2.0.
You can also use the environment variable $window so that a global variable declare outside a controller can be checked inside a $watch
var initWatch = function($scope,$window){
$scope.$watch(function(scope) { return $window.globalVar },
function(newValue) {
$scope.updateDisplayedVar(newValue);
});
}
Becareful, the digest cycle is longer with these global values, so it is not always real-timed updated. I need to investigate on that digest time with this configuration.
I just found another method by mistake :
What I did was to declare a var db = null above app declaration and then modified it in the app.js then when I accessed it in the controller.js
I was able to access it without any problem.There might be some issues with this method which I'm not aware of but It's a good solution I guess.
Try this, you will not force to inject $rootScope in controller.
app.run(function($rootScope) {
$rootScope.Currency = 'USD';
});
You can only use it in run block because config block will not provide you to use service of $rootScope.
It's actually pretty easy. (If you're using Angular 2+ anyway.)
Simply add
declare var myGlobalVarName;
Somewhere in the top of your component file (such as after the "import" statements), and you'll be able to access "myGlobalVarName" anywhere inside your component.
You can also do something like this ..
function MyCtrl1($scope) {
$rootScope.$root.name = 'anonymous';
}
function MyCtrl2($scope) {
var name = $rootScope.$root.name;
}

Global variables in AngularJS

I have a problem where i'm initialising a variable on the scope in a controller. Then it gets changed in another controller when a user logs in. This variable is used to control things such as the navigation bar and restricts access to parts of the site depending on the type of user, so its important that it holds its value. The problem with it is that the controller that initialises it, gets called again by angular some how and then resets the variable back to its initial value.
I assume this is not the correct way of declaring and initialising global variables, well its not really global, so my question is what is the correct way and is there any good examples around that work with the current version of angular?
You've got basically 2 options for "global" variables:
use a $rootScope http://docs.angularjs.org/api/ng.$rootScope
use a service http://docs.angularjs.org/guide/services
$rootScope is a parent of all scopes so values exposed there will be visible in all templates and controllers. Using the $rootScope is very easy as you can simply inject it into any controller and change values in this scope. It might be convenient but has all the problems of global variables.
Services are singletons that you can inject to any controller and expose their values in a controller's scope. Services, being singletons are still 'global' but you've got far better control over where those are used and exposed.
Using services is a bit more complex, but not that much, here is an example:
var myApp = angular.module('myApp',[]);
myApp.factory('UserService', function() {
return {
name : 'anonymous'
};
});
and then in a controller:
function MyCtrl($scope, UserService) {
$scope.name = UserService.name;
}
Here is the working jsFiddle: http://jsfiddle.net/pkozlowski_opensource/BRWPM/2/
If you just want to store a value, according to the Angular documentation on Providers, you should use the Value recipe:
var myApp = angular.module('myApp', []);
myApp.value('clientId', 'a12345654321x');
Then use it in a controller like this:
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
this.clientId = clientId;
}]);
The same thing can be achieved using a Provider, Factory, or Service since they are "just syntactic sugar on top of a provider recipe" but using Value will achieve what you want with minimal syntax.
The other option is to use $rootScope, but it's not really an option because you shouldn't use it for the same reasons you shouldn't use global variables in other languages. It's advised to be used sparingly.
Since all scopes inherit from $rootScope, if you have a variable $rootScope.data and someone forgets that data is already defined and creates $scope.data in a local scope you will run into problems.
If you want to modify this value and have it persist across all your controllers, use an object and modify the properties keeping in mind Javascript is pass by "copy of a reference":
myApp.value('clientId', { value: 'a12345654321x' });
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
this.clientId = clientId;
this.change = function(value) {
clientId.value = 'something else';
}
}];
JSFiddle example
Example of AngularJS "global variables" using $rootScope:
Controller 1 sets the global variable:
function MyCtrl1($scope, $rootScope) {
$rootScope.name = 'anonymous';
}
Controller 2 reads the global variable:
function MyCtrl2($scope, $rootScope) {
$scope.name2 = $rootScope.name;
}
Here is a working jsFiddle: http://jsfiddle.net/natefriedman/3XT3F/1/
In the interest of adding another idea to the wiki pool, but what about AngularJS' value and constant modules? I'm only just starting to use them myself, but it sounds to me like these are probably the best options here.
Note: as of the time of writing, Angular 1.3.7 is the latest stable, I believe these were added in 1.2.0, haven't confirmed this with the changelog though.
Depending on how many you need to define, you might want to create a separate file for them. But I generally define these just before my app's .config() block for easy access. Because these are still effectively modules, you'll need to rely on dependency injection to use them, but they are considered "global" to your app module.
For example:
angular.module('myApp', [])
.value('debug', true)
.constant('ENVIRONMENT', 'development')
.config({...})
Then inside any controller:
angular.module('myApp')
.controller('MainCtrl', function(debug, ENVIRONMENT), {
// here you can access `debug` and `ENVIRONMENT` as straight variables
})
From the initial question is actually sounds like static properties are required here anyway, either as mutable (value) or final (constant). It's more my personal opinion than anything else, but I find placing runtime configuration items on the $rootScope gets too messy, too quickly.
// app.js or break it up into seperate files
// whatever structure is your flavor
angular.module('myApp', [])
.constant('CONFIG', {
'APP_NAME' : 'My Awesome App',
'APP_VERSION' : '0.0.0',
'GOOGLE_ANALYTICS_ID' : '',
'BASE_URL' : '',
'SYSTEM_LANGUAGE' : ''
})
.controller('GlobalVarController', ['$scope', 'CONFIG', function($scope, CONFIG) {
// If you wish to show the CONFIG vars in the console:
console.log(CONFIG);
// And your CONFIG vars in .constant will be passed to the HTML doc with this:
$scope.config = CONFIG;
}]);
In your HTML:
<span ng-controller="GlobalVarController">{{config.APP_NAME}} | v{{config.APP_VERSION}}</span>
localStorage.username = 'blah'
If you're guaranteed to be on a modern browser. Though know your values will all be turned into strings.
Also has the handy benefit of being cached between reloads.
Please correct me if I'm wrong, but when Angular 2.0 is released I do not believe$rootScope will be around. My conjecture is based on the fact that $scope is being removed as well. Obviously controllers, will still exist, just not in the ng-controller fashion.Think of injecting controllers into directives instead. As the release comes imminent, it will be best to use services as global variables if you want an easier time to switch from verison 1.X to 2.0.
You can also use the environment variable $window so that a global variable declare outside a controller can be checked inside a $watch
var initWatch = function($scope,$window){
$scope.$watch(function(scope) { return $window.globalVar },
function(newValue) {
$scope.updateDisplayedVar(newValue);
});
}
Becareful, the digest cycle is longer with these global values, so it is not always real-timed updated. I need to investigate on that digest time with this configuration.
I just found another method by mistake :
What I did was to declare a var db = null above app declaration and then modified it in the app.js then when I accessed it in the controller.js
I was able to access it without any problem.There might be some issues with this method which I'm not aware of but It's a good solution I guess.
Try this, you will not force to inject $rootScope in controller.
app.run(function($rootScope) {
$rootScope.Currency = 'USD';
});
You can only use it in run block because config block will not provide you to use service of $rootScope.
It's actually pretty easy. (If you're using Angular 2+ anyway.)
Simply add
declare var myGlobalVarName;
Somewhere in the top of your component file (such as after the "import" statements), and you'll be able to access "myGlobalVarName" anywhere inside your component.
You can also do something like this ..
function MyCtrl1($scope) {
$rootScope.$root.name = 'anonymous';
}
function MyCtrl2($scope) {
var name = $rootScope.$root.name;
}

Resources