Angularjs - stop loading application - angularjs

I would like to ask how to stop loading application. I need this for showing modal window with login form. My idea is:
User go to my webpage, first start LoginController which check if user is authenticated. If not, it displays the form but must be stopped loading next controllers and components (loading data by user id).
Here is my concept:
<body ng-controller="LoginController">
controllers, components...
</body>
app.controller("LoginController", function LoginController(){
this.$onInit = function(){
if(!authenticated()){
showLoginModal();
stopLoadingApp(); // what will be implementation?
}
}
})
I tried this, but not called:
app.controller("LoginController", function LoginController($rootScope){
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
event.preventDefault(); //not called
});
});
Please help me how to solve this problem. Thanks

Related

AngularJS routeChangeStart not working when on homepage

I can capture the Back Button in an AngularJs app using the $locationChangeStart event, so I can close a modal.
This works when I navigate away from the first page and then click a modal, then click back, I capture the Back event and close the modal and prevent the browser back default.
The problem is it does not work when on the homepage, none of the events get fired so I can't prevent default and close the modal, it just goes back to the new tab page (google)
$rootScope.$on("$locationChangeStart", function (event, next, current) {
event.preventDefault();
console.log('$locationChangeStart 1 ');
});
$rootScope.$on('$routeChangeStart', function (scope, next, current) {
event.preventDefault();
console.log('$routeChangeStart');
});
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
event.preventDefault();
console.log('$stateChangeStart');
});
$rootScope.$on('$destroy', function (event, next, current) {
event.preventDefault();
console.log('$locationChangeStart');
});
I'm using $routeProvider and don't really want to have to re-write it in ui-router.
Is there some config I have missed to get these events to fire when on my first page? or is there a hack?
thanks

UI-router : $state.current.name shows empty

Sometimes state which i define is not render and shows blank page.
And at this time when i try to see from console which state is this, it shows like below.
state name shows empty, which is not defined in my app.
Anybody know about this issue please help me.
I am guessing you see the full object in console because it gets filled later and the browser reacts..
Try to include your block with $state into a $timeout(). It's a trick to wait for the $digest cycle to be over before getting the value.
$timeout(function() { console.log($state.current.name); });
or
$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams) {
var statename = toState.name
console.log(statename) })

Can't get $anchorScroll working on $stateChangeSuccess?

I'm trying to adapt the answer give in this similar question How to handle anchor hash linking in AngularJS. I need to be able to use it with ui-router. I've tested anchor scrolling as a clickable function in my controller and that is working. Here is the code for that
$scope.anchor = function () {
console.log('test');
$location.hash('comments');
$anchorScroll();
};
If I try to invoke that function immediately nothing happens
$scope.anchor();
If I try to invoke it on a $stateChangeSuccess nothing happens. I threw in a log for sanity and that is firing. I also tried a trick to prevent further routing logic from kicking in. It was mentioned in the linked post but I'm not sure if it's necessary for my case.
app.run(function ($rootScope, $location, $stateParams, $anchorScroll) {
// allow anchorScrolling
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
console.log('stateChangeSuccess');
var old = $location.hash();
$location.hash('comments');
$anchorScroll();
//reset to old to keep any additional routing logic from kicking in
$location.hash(old);
});
});
I'm guessing that I'm running into race conditions or my anchor scroll is somehow triggering another route change. But I can't figure out how to track these issues down. Any thoughts?
EDIT: Update I removed the $location.hash(old); and put the rest of the $anchorScroll pieces into a timeout function and it's now working. I also added in the $stateParams.scrollTo to make this useable with query params. Any ideas as to what is causing my race condition and how this might be solved without a $timeout function?
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
console.log('stateChangeSuccess');
$timeout(function() {
$location.hash($stateParams.scrollTo);
$anchorScroll();
}, 300);
});
From $anchorScroll documentation
It also watches the $location.hash() and scrolls whenever it changes to match any anchor. This can be disabled by calling $anchorScrollProvider.disableAutoScrolling().
Try removing $location.hash(old);
If that fixes it, use $anchorScrollProvider.disableAutoScrolling() to disable it reacting to another state change.

Closing a modal automatically on navigation (when clicking an anchor)

I'm using angular-ui modal in my webapp. one of models display many links (anchor elements) that navigate to various parts of the app. the modal can be closed as usual with modal.dismiss() or modal.close(). but I need it to close when someone navigate out of it with clicking an anchor? usually (not angular) I could just attach an event to all the anchor clicks and close the modal from there. but in angular It seems somewhat complicated and not very "angularish" - Any ideas/directions on how to implement this?
e.g: I'm using angular-ui-router so if this can be solved through the routes It would also solve my problem.
Thanks!
Angular-ui-router fires events when a state change has occurred, so in your controller you could do something like:
$scope.currentModal = undefined;
// whenever a modal opens, ensure it is assigned to the $scope.currentModal. Not clear how
// you are managing your modals at the moment.
// this event-listener closes the current modal (if any)
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
if ($scope.currentModal) {
$scope.currentModal.dismiss();
}
})
Use $modalStack.dismissAll() to close any modalbox when state changes.
angular.module('myApp').controller('AppCtrl', ['$scope', '$rootScope', '$modal', '$modalStack',
function ($scope, $rootScope, $modal, $modalStack) {
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams, options){
$modalStack.dismissAll();
});
}
]);

Updating title tag using AngularJS and UI-Router

I am running into a weird issue while trying to set the title of the page using the name of the current state (via ui-router).
Actually, the issue is not with setting the title, the issue is that the title gets set to the title of the next state before the history.pushState. So when I transition to a new url, the first item in the history has the same name as the current page.
I was just playing around with the sample (http://angular-ui.github.io/ui-router/sample/) and I managed to reproduce it there as well. If you click on About, then back on home you will see 2 different entries for 'home'. They both point to the correct url, but their names are mangled. Weirdly enough, clicking through the Contact.list and contact.details sets the history properly.
Is there a way around this? When in the pipeline does the history.pushstate get called?
I had a 'similar' situation... and answered it here.
It basically defines $rootScope.$state = $state inside of the run method of angular. That allows us to access current states info in templates.
<title ng-bind="$state.current.data.pageTitle"></title>
The key is defining it on the $rootScope in the run method.
I have a similar situation like yours and I do it like the following.
You can put that in your main app run block like following.
I had
angular.module('myApp').run([
'$log', '$rootScope', '$window', '$state', '$location',
function($log, $rootScope, $window, $state, $location) {
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
if (toState.title) {
$rootScope.pageTitle = toState.title;
}
});
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
// something else
});
$state.go('home');
}
]);
and in the html head i have
<html class="no-js" class="ng-app" ng-app="..." id="ng-app">
<head>
....
<title ng-bind="pageTitle"></title>
hope this works for you.
PS: Please consult https://docs.angularjs.org/guide/module for details.
I wrote the angular-ui-router-title plugin for this. You can use it to update the page title to a static or dynamic value based on the current state. It correctly works with browser history, too.

Resources