I have a javascript object which I need global to my angularjs application. When the application is about to be unloaded (due to a page refresh or some other scenario), I would like to persist the object to browser storage. I believe adding the object to $rootScope would fulfill the first requirement of making the object global, but writing the object to storage during the onbeforeunload event, would require access to the $rootScope variable. Is it possible to detect a page unload event in angularjs?
This should do it, but I also suggest avoiding $rootScope as global state is discouraged, and you might also wrap localStorage in a service so that it can be injected and mocked for testing.
.run([
'$window',
'$rootScope',
function($window, $rootScope) {
$window.addEventListener('beforeunload', function() {
localStorage.myValue = $rootScope.myValue;
});
}
]);
Related
I am new to AngularJS and I am confused when to use them and why they were built if native JavaScript object could have served the purpose. The AngularJS services in question are $location, $window, $document etc.
Most of the services doesn't really do anything. For example $window is just window wrapped in function and provider. But in a few cases you have to use services provided by AngularJS to remain in it's scope so your app can track changes. Any code that runs outside of AngularJS framework isn't tracked by it, so if you would use:
setTimeout(() => {
console.log("This is outside AngularJS scope.");
this.myName = "John";
}, 1000);
HTML binded to 'myName' wouldn't be updated. You'd have to call $digest so AngularJS could refresh changes or wrap your code in $apply(() => { your code }). So that's why AngularJS provides these services. Which are just default functions provided by browser but wrapped in $apply function.
I think the primary purposes of these services are for mocking or testing the application. They are also limited to the current scope so you don't have to worry about accidentally overwriting stuff in the global object.
Another small advantage is that dependencies when uglyfied are replaced while the global object window would stay the same.
I have an Angular js factory. In which I am storing the user information after successful login. Now I have multiple controllers in all of them I need this user information so I need to inject this factory to each and every controller. Is there any way to access this factory data throughout the project without injecting in each and every controller?
Can we directly inject it into the module?
Some suggestions :
storing the user information in factory is not a good approach because if user reload the page it will reset the factory data and user will not exist anymore.
As sajeetharan suggested, you can use HTML5 localStorage or sessionStorage to store the user information. So, that without injecting you can easily access stored storage value everywhere you want.
Yes, if you need the user information so you need to inject the factory to each and every controller because on switching from one controller to another controller you have to fetch the data from the factory.If you inject the factory only in the main module it will not load the factory when you move from success login to some other page.
User information can be stored in local storage or cookie so that i can be accessed anywhere.
You can also consider using $rootScope, in that case also you need to inject in all the modules which you require.
a factory is part of a module.
Injecting it into the controllers needed is the way of using the saved values throughout the module.
I only see .config with passing $routeProvider, what else will passing through by .config and also want to know what are the parameters will pass through by .run in angularjs
These are dependency injected services.
So for config you should be asking for constant or provider. For run you should be asking for service, factory, value, constant.
You should notice i'm saying should be asking for, because we're dependency injecting the services, the function parameters are effectively asking angular DI for particular instances. If angular has one it will supply the function arg with that instance, similar to a fn.call({}, someDep)
So for example:
angular.module('myMod', [])
.provider('myFactory', myFactoryProvider)
.factory('anotherService', anotherServiceFactory)
.config(function (myFactoryProvider) {
})
.run(function (myFactory, anotherService) {
/** myFactory is the service that was setup
* by the config myFactoryProvider
*/
});
I've left out the implementations for myFactoryProvider and anotherServiceFactory so you look up angular docs to see what they're about.
The config and run describe the phases of an angular application. config phase is for setting up services and pipelines like the $http request pipeline and generally pre-app configuration.
The run phase is for when the app has loaded and you want to do something like load some user information from the api or anything else post-app load.
I personally used to use the config all the time with $stateProvider and things. But, I rarely used the run function.
I have a AngularJS app, that depends on a webservice, I would like to load some more controllers into the app from a remote host, after the app is loaded. I don't know i this is possible?
In my controller, I want to load some more controllers (js files)
.controller('FrontpageCtrl', function($scope, $stateParams, $filter, $sce, contentService) {
console.log("hitting FrontpageCtrl ... ");
contentService.promise.then(function(data){
var page = $filter('filter')(data, {id:$stateParams.pageId})[0];
$scope.content = $sce.trustAsHtml(page.content);
// Load a controller, directive and other provided by the webservice!
$scope. ...
});
})
Currently angular does not provide a way to load modules dynamically. Hence, any angular built in object (directives, controllers, factories, etc.). This means your controllers (from the web service) should be loaded on bootsrapping angular (probably as a resource on the index page).
There are some ways to dynamically load stuff after bootstrapping, here are a few:
My personal favorite: https://github.com/ocombe/ocLazyLoad.
Closest to your question: http://weblogs.asp.net/dwahlin/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs
https://www.startersquad.com/blog/angularjs-requirejs/
There are many more stuff to be found.. you can obviously google it.
In my application I need to make a couple of request, using $http, and store the data in the $rootScope before the routes is executed. Is there a way to do this?
There is the run method:
angular.module('yourModule').run(['$rootScope', '$http',
function($rootScope, $http) {
$rootScope.foo = 'foo';
}
]);
This is executed before the routing starts.
HOWEVER, it is not good practice to store lots of global data in the $rootScope. It is better to use a service (also possible in the run method) and inject the service in your controllers only when you really need it.