Debugging angular ui-router under ionic - angularjs

I am pretty new to Angularjs and Ionic and I am trying to warp my head around the status based routing. The biggest hurdle is that it seems to difficult to drill in without a decent way to debug what's happening.
There is some help for debugging angularjs ui-routing in this question and answer - But the example is for just AngularJS and not for Ionic and I am struggling to figure out how to implement this solution in Ionic.
In AngularJS the debug code would go here:
angular.module('MyModule').run(['$rootScope',function($rootScope){ // put the event handlers here }]);
But in Ionic the according code looks like this:
run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
Can anyone help me understand how to inject the debug code here?

Thanks to the comment from George Stocker I figured it out. The resulting code looks like this:
angular.module('starter', [])
.run(['$rootScope',function($rootScope){
$rootScope.$on('$stateChangeStart',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeStart to '+toState.to+'- fired when the transition begins. toState,toParams : \n',toState, toParams);
});
$rootScope.$on('$stateChangeError',function(event, toState, toParams, fromState, fromParams, error){
console.log('$stateChangeError - fired when an error occurs during transition.');
console.log(arguments);
});
$rootScope.$on('$stateChangeSuccess',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeSuccess to '+toState.name+'- fired once the state transition is complete.');
});
$rootScope.$on('$viewContentLoaded',function(event){
console.log('$viewContentLoaded - fired after dom rendered',event);
});
$rootScope.$on('$stateNotFound',function(event, unfoundState, fromState, fromParams){
console.log('$stateNotFound '+unfoundState.to+' - fired when a state cannot be found by its name.');
console.log(unfoundState, fromState, fromParams);
});
}])

Here you can inject the AngularJS logging service to your Ionic project, in just one run method call:
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
.run(['$rootScope', '$log', '$ionicPlatform', function ($rootScope, $log, $ionicPlatform) {
$ionicPlatform.ready(function () {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
// Debug stuff...
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
$log.debug('$stateChangeStart to ' + toState.name + '- fired when the transition begins. toState,toParams : \n', toState, toParams);
});
$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
$log.debug('$stateChangeError - fired when an error occurs during transition.');
$log.debug(arguments);
});
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
$log.debug('$stateChangeSuccess to ' + toState.name + '- fired once the state transition is complete.');
});
// $rootScope.$on('$viewContentLoading',function(event, viewConfig){
// // runs on individual scopes, so putting it in "run" doesn't work.
// $log.debug('$viewContentLoading - view begins loading - dom not rendered',viewConfig);
// });
$rootScope.$on('$viewContentLoaded', function (event) {
$log.debug('$viewContentLoaded - fired after dom rendered', event);
});
$rootScope.$on('$stateNotFound', function (event, unfoundState, fromState, fromParams) {
$log.debug('$stateNotFound ' + unfoundState.name + ' - fired when a state cannot be found by its name.');
$log.debug(unfoundState, fromState, fromParams);
});
}])
For production you can disable debug, with this in your config block:
.config(function($logProvider){
$logProvider.debugEnabled(false);
});

Related

Angular JS, unable to get handle to rootScope [duplicate]

This question already has answers here:
Cannot get to $rootScope
(3 answers)
Closed 5 years ago.
I am using angular 1.5.x
Below is my routing logic but I am not able to get a handle of the rootScope.
Please can you advise what could be wrong?
UPDATE: I have updated the routing logic as per the answer post below.
I am still not able to hit the controller.
(function() {
'use strict';
angular
.module('icebergApp')
.config(setupRouting);
setupRouting.$inject = ['$stateProvider', '$urlRouterProvider', '$rootScope'];
function setupRouting($stateProvider, $urlRouterProvider, $rootScope) {
$urlRouterProvider.otherwise("/iceberg-ui");
$stateProvider
.state('iceberg.reconlist', {
url: "/iceberg-ui",
templateUrl: "app/iceberg/reconlist/reconlist.view.html",
controller: 'ReconListController as vm'
})
$rootScope.$on('$stateChangeStart',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeStart to '+toState.name+'- fired when the transition begins. toState,toParams : \n',toState, toParams);
});
$rootScope.$on('$stateChangeError',function(event, toState, toParams, fromState, fromParams, error){
console.log('$stateChangeError - fired when an error occurs during transition.');
console.log(arguments);
});
$rootScope.$on('$stateChangeSuccess',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeSuccess to '+toState.name+'- fired once the state transition is complete.');
});
$rootScope.$on('$viewContentLoading',function(event, viewConfig){
console.log('$viewContentLoading - view begins loading - dom not rendered',viewConfig);
});
$rootScope.$on('$stateNotFound',function(event, unfoundState, fromState, fromParams){
console.log('$stateNotFound '+unfoundState.to+' - fired when a state cannot be found by its name.');
console.log(unfoundState, fromState, fromParams);
});
}
}());
CONTROLLER
(function() {
'use strict';
var myApp = angular.module('iceberg.reconlist', ['ui.router']);
myApp.controller('ReconListController', ReconListController);
ReconListController.$inject = ['ReconListService'];
function ReconListController(ReconListService) {
var vm = this;
}
}());
MODULE
(function() {
'use strict';
angular.module('icebergApp', [
'ui.router',
'iceberg.reconlist'
]);
angular.module('iceberg.reconlist', [
]);
}());
$rootScope is not available in .config(). Only providers are available there. The thing you must do is splitting your code to put the $rootScope part into a .run method.
angular
.module('app')
.config(setupRouting);
setupRouting.$inject = ['$stateProvider', '$urlRouterProvider'];
function setupRouting($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/iceberg-ui");
$stateProvider
.state('iceberg.reconlist', {
url: "/iceberg-ui",
templateUrl: "app/iceberg/reconlist/reconlist.view.html",
controller: 'ReconListController as vm'
})
}
}());
angular.module('app').run(setupRoutingEventListeners);
setupRouting.$inject = ['$rootScope'];
function setupRoutingEventListeners($rootScope) {
$rootScope.$on('$stateChangeStart',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeStart to '+toState.name+'- fired when the transition begins. toState,toParams : \n',toState, toParams);
});
$rootScope.$on('$stateChangeError',function(event, toState, toParams, fromState, fromParams, error){
console.log('$stateChangeError - fired when an error occurs during transition.');
console.log(arguments);
});
$rootScope.$on('$stateChangeSuccess',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeSuccess to '+toState.name+'- fired once the state transition is complete.');
});
$rootScope.$on('$viewContentLoading',function(event, viewConfig){
console.log('$viewContentLoading - view begins loading - dom not rendered',viewConfig);
});
$rootScope.$on('$stateNotFound',function(event, unfoundState, fromState, fromParams){
console.log('$stateNotFound '+unfoundState.to+' - fired when a state cannot be found by its name.');
console.log(unfoundState, fromState, fromParams);
});
}

How to detect state start completion with a combination of $stateChangeStart, $stateChangeSuccess, $state with ui-router for angularjs

I want to impliment a loader image for each state change, and that will be apply to the whole page whenever the state changes. I tried to at least see if they exist, but somehow, I receive not definfed for $stateChangeStart for both when state change start and completed. I wonder what is the best way to do it? Because I want to put that $stateChangeStart as a var for ng-hide directive, so that when every time a state change starts, the loader will show, and (I assume) when $stateChangeSuccess is becoming defined, then its change of state is completed?
Please advice if anything of what I intent to do is wrong and better way to do it. Because I want to build the loader to be directive by itself and its reusable.
Below is the code I try to test these 3 objects.
app.run([
'$rootScope','$location','$state','$stateParams',/*'$templateCache',*/
function (
$rootScope, $location, $state, $stateParams/*, $templateCache*/ ) {
console.log("app run")
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
console.log("state start-------------------------")
console.log($stateChangeStart,"$stateChangeStart ")
console.log($stateChangeSuccess,"$stateChangeSuccess ")
console.log($state);
});
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
console.log("state $stateChangeSuccess-------------------------")
console.log($stateChangeStart,"$stateChangeStart ")
console.log($stateChangeSuccess,"$stateChangeSuccess ")
console.log($state);
});
}]);
Try something like this:
app.run([
'$rootScope','$location','$state','$stateParams',/*'$templateCache',*/
function (
$rootScope, $location, $state, $stateParams/*, $templateCache*/ ) {
console.log("app run")
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
$rootScope.showLoading = true;
});
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
$rootScope.showLoading = false;
});
}]);
and then bind the ng-show to the showLoading property.

Angular, ui-router: show loading when change state

Is there a way in angular that when I want switch to another state (ui-sref) that i can show some load icon until the second state is loaded?
yes angular ui.router has events which you can listen:
$stateChangeStart - fired when the transition begins.
$stateChangeSuccess - fired once the state transition is complete.
following this you can write preloader functionality
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
$rootScope.preloader = false;
}
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
$rootScope.preloader = true;
}
and write some <div> in your body element and show/hide it with this variable
eg.
<body>
<div ng-show="preloader"></div>
</body>

ui-router change, when to remove the old html

I've tested this in chrome, and added a break in the $scope.init in Ctrl2
but then when I go to route2 from route1, the chrome debugger stays at $scope.init of Ctrl2, but I see that ctrl1.html is still there.
.state("main.route1", {
url: "/route1",
controller: 'Ctrl1',
templateUrl: 'views/ctrl1.html'
})
.state("main.route2", {
url: "/route2",
controller: 'Ctrl2',
templateUrl: 'views/ctrl2.html'
})
So, how does the ui-router work? Isn't it supposed to go to ctrl2.html, and then execute Ctrl2? Why did it enter Ctrl2 but the ctrl1.html is still displayed?
I'm not sure if it is the same in ng-view, I haven't tested that.
Check js console to make sure you don't have errors in your angular controller
Add following run block to your module to catch state change error
.run(function ($rootScope, $state) {
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
console.log(fromState.name + ' to ' + toState.name);
});
$rootScope.$on('$stateChangeError',
function (event, toState, toParams, fromState, fromParams, error) {
alert(error);
event.preventDefault();
});
});

How to $watch state change of $stateProvider in AngularJS?

I know that I can run:
scope.$watch(someItem, function(){})
But I can't figure out a way to watch over change of $state.$current.name in my application.
It's in the docs: https://github.com/angular-ui/ui-router/wiki#state-change-events
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
// do something
})
This works:
$scope.$watch(function(){
return $state.$current.name
}, function(newVal, oldVal){
//do something with values
})

Resources