How to create a global state change handler with ui-router - angularjs

I'm building my first angular app and many of the major features are separated into their own modules. Each module registers its routes in config with $stateProvider.
I want to be able to handle $stateChangeStart/$stateChangeError in one place for my whole app so I can evaluate authorization and handle errors. How do I do this?
Currently I have this handler registered on $rootScope on my main module/app but if I navigate to a route from another module and then navigate to another route it does not fire. Why? In fact even $urlRouterProvider.otherwise("xyz"); no longer works.
I don't like copy pasting code so any solution that avoids putting this logic in every module would be appreciated.

You can try something like:
var app = {};
// Route Config for a "some" module.
function someModuleConfig($stateProvider) {
$stateProvider.
state('something', {
url: '/something',
templateUrl: 'path/to/something/something.html',
});
}
// Module definition for "some" module.
app.somemodule.module = angular.module('app.somemodule', []).
config(someModuleConfig);
// Route Config for the main module.
function appConfig($stateProvider, $urlRouterProvider) {
// Set the default redirect for any missing route.
$urlRouterProvider.otherwise('xyz');
$stateProvider.
state('home', {
url: '/',
templateUrl: 'path/to/home/home.html'
});
};
// Module definition for the main module.
app.module = angular.module('myapp', [
'ui.router',
app.somemodule.name
]).config(appConfig);
The key is that you can register your routes with the main module, and subroutes can be registered in other modules. You could also register all your routes in the main app module as well, depending on how you structure your code.

Related

Angular Js + UI router, more than one module each with each owns ui routes config - how?

I have a main app on my application, called "bionico", this app utilizes UI-router
It has it's own $stateProvider configurations!
And that's fine, it works
BUT I needed to create a new module (cuz I'm trying to insert a step-by-step form on my application, you can find the code here: https://scotch.io/tutorials/angularjs-multi-step-form-using-ui-router)
To make this step-by-step form I need to create a new module with it's own $stateProvider configurations, the thing is that it doesn't work, I have included this module called "bionico.formApp" in my main app like this:
angular.module('bionico', ['ui.router', other modules, 'bionico.formApp'])
And that works fine, if I try to use a controller inside "bionico.formApp" it will also work fine. This is the code for this module:
// create our angular app and inject ngAnimate and ui-router
// =============================================================================
angular.module('bionico.formApp', ['ngAnimate', 'ui.router', ])
// configuring our routes
// =============================================================================
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('form', {
url: '/form',
templateUrl: 'templates/campaignForm/form.html',
controller: 'formCtrl'
})
// nested states
// each of these sections will have their own view
// url will be nested (/form/profile)
.state('form.profile', {
url: '/profile',
templateUrl: 'templates/campaignForm/form-profile.html'
})
// url will be /form/interests
.state('form.interests', {
url: '/interests',
templateUrl: 'templates/campaignForm/form-interests.html'
})
// url will be /form/payment
.state('form.payment', {
url: '/payment',
templateUrl: 'templates/campaignForm/form-payment.html'
})
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/form/profile');
})
// our controller for the form
// =============================================================================
.controller('formCtrl', function($scope) {
// we will store all of our form data in this object
$scope.formData = {};
$scope.test = "FUNCIONA";
// function to process the form
$scope.processForm = function() {
alert('awesome!');
};
});
But to make this form work I need to use <div ui-view></div> and when I put this on my file nothing happens, and I think it's because the app is using my main module "bionico" $stateProvider configurations and not "bionico.formApp"
Here is my html code:
<div ng-controller="formCtrl">
<!-- views will be injected here -->
<div ui-view></div>
{{test}}
the {{test}} from formCtrl works fine, it is printing the variable on my screen, but like I said ui-view is not. Is there a way to tell angular that I want to use "bionico.formApp" configurations and not the configs from my main module?
How would you solve this?
Like I think I have to tell angular that from that moment on I want to use "bionico.formApp" but I don't know how to do it.
I've tried
<div ng-app="bionico.formApp"> but nothing happened, not even errors
I saw then on stack over flow that I have to bootstrap it manually, but then I got an error saying that "bionico.formApp" had already been bootstraped
Update
People suggested that I only needed to rout stuff in only one module, but I needed two different default routs one for my main application and one or my form, but that wouldn't work.
and the reason why I was trying to make this work was because I needed a step by step form (wizard) on my application like this one: https://scotch.io/tutorials/angularjs-multi-step-form-using-ui-router)
But I've decided it is not worth the hassle, I'll try to find another wizard for angular js
I'm using now this walktrough wizard:
https://github.com/mgonto/angular-wizard
It was easy to install and it is very easy to customize the template, I recommend!

How do you attach a controller MEAN.IO home route

The MEAN.IO route for home is controlled by the viewPathProvider. In the MEAN.IO docs they say that you can overload the home page by overloading the viewPathProvider config in your module.
angular.module('custom-package')
.config(['$viewPathProvider', function($viewPathProvider) {
$viewPathProvider.override('system/views/index.html', 'custom-path');
}]);
However its not specified how to add an (AngularJS) controller to the view that is being loaded or how to associate a controller to it.
Hint in the system route there is a route where you can specify a controller but I would rather do this from my own package
//Line 49 In system.js under system/public/routes
$meanStateProvider
.state('home', {
url: '/',
templateUrl: 'system/views/index.html'
//I can add a controller here but it will be stuck in the system package
});
I also don't want to specify the controller in the HTML as most of my application is built with controllers specified in the route

AngularJS Routing Configuration not called

I am running through a course at the moment on AngularJS and it has just introduced the concept of routing.
My problem is the app.config function is setup in app.js however, the function doesn't seem to ever be called and therefore the routes are not setup.
The common problem is the ngRoute not being declared however, it is. I'm not sure if there is a problem with the versions of Angular that I'm using but these were taken from the online course.
I have a public plnkr for anyone to view and have a look at http://plnkr.co/edit/L2FG4M?p=preview
(function() {
var app = angular.module("githubViewer", ["ngRoute"]);
app.config(function($routeProvider) {
// If we navigate to /main then the page used will be main.html and the controller
// MainController, if however something else is provided then we will
// redirect to /main as well
$routeProvider.when("/main", {
templateUrl: "main.html",
controller: "MainController"
})
.otherwise({
redirectTo: "/main"
});
});
}());
Any help is appreciated, I've exhausted my options now.
Thanks
Marc
In your MainController.js file, you defined a new module with same name as in app.js:
angular.module("githubViewer", []);
What you want to do is retrieve the already defined module. You can acheive that by removing the []:
angular.module("githubViewer");
Look here at the "Creation versus Retrieval" section.

Is there a pattern for reusing a resolver across modules in angularJS

I have a modular structure to my App meaning I have many config files with route definition in them. I am trying to use a resolver to check if the user is authenticated or not before I move them to the next route view.
right now I can reuse a function in the config as my resolve method i.e.
function resolverFunc(Auth, $state){
if(!Auth.isLoggedIn()){
$state.go('login');
}
}
$stateProvider.state('state1', {
url: "/myurl",
resolver:{
loggedIn: resolverFunc
}
}
)
.state('state2',{
url: '/url2',
resolver:{
loggedIn: resolverFunc
}
})
the problem is that I have to define the resolverfunc in every module. Because every module has it's own module.config() where the routes are defined for that module.
Is there a simpler solution. I hate to have to re-write this function in every config file for all the modules with routes

AngularJS: Adding new routes dynamically

As we use, $routeProvider in config method, as of my knowledge $route is a provider.
So, I tried adding new routes to $route in my controller:
After configuring and bootstrapping the application, somewhere in my controller, I tried this:
app.controller('MyCtrl',function($scope,$route) {
$route.routes['/newRoute'] = { template : 'hey, this is dynamically added route' };
});
But this doesn't seem to work. why?
Any Ideas?
you can only configure the routes via your ngapp config function only, so you can't just add routes dynamically in runtime.
also $route is a service.

Resources