Some time ago I had a work task required to make dynamic routing in App.config method of AngularJS application.
Initially I wanted to do something like this:
someApp.config(['$routeProvider', '$httpProvider',
'$compileProvider', 'settings',
function ($routeProvider, $httpProvider,
$compileProvider, settings) {
var $http = angular.injector(['ng']).get('$http');
var $q = angular.injector(['ng']).get('$q');
var isUserLogged = $q.defer();
$http.get(settings.apiUri + settings.loginStatus).
success(function (data) {
if (data.status == "NOT_LOGGED") {
isUserLogged.reject();
} else {
isUserLogged.resolve();
}
});
isUserLogged.promise.
catch(function () {
$routeProvider.
when('/home', {
templateUrl: 'partials/home.html',
controller: 'HomeController'
}).
otherwise({
redirectTo: '/home'
});
});
isUserLogged.promise.
then(function () {
$routeProvider.
when('/accountsettings', {
templateUrl: 'partials/accountsettings.html',
controller: 'AccountSettingsController'
}).
otherwise({
redirectTo: '/accountsettings'
});
});
}]);
But routing did not work because .config method behaves as synchronous.
When I remove the http query and promice logic everything worked perfectly.
I asked a question in stackoverflow, but there was no answer.
After reading the documentation and digging I came to the decision that satisfy me.
I did a manual bootstrapping of the application. First I make request to determine
whether the user is logged or not. Then I trigger custom event listener whose call .config
method of application and do routing in accordance whether the user is logged or not.
Below is the code of the decision to which I got (with abbreviations).
angular.element(document).one("userStatusIsCheked",
function(event, userIsLogged) {
appName.config(['$routeProvider',
'$httpProvider', '$compileProvider',
function ($routeProvider,
$httpProvider, $compileProvider) {
if (userIsLogged == true) {
$routeProvider.
when('/resetpassword/:hashValue', {
templateUrl: 'partials/home.html',
controller: 'ResetPasswordController'
}).
when('/accountsettings', {
templateUrl: 'partials/accountsettings.html',
controller: 'AccountSettingsController'
}).
when('/changepassword',
{
templateUrl:
'partials/accountsettingschangepassword.html',
controller: 'ChangePasswordController'
}).
when('/edit', {
templateUrl: 'partials/accountsettingsedit.html',
controller: 'EditAccountController'
}).
when('/apikeymanagement', {
templateUrl: 'partials/apikeymanagement.html',
controller: 'APIKeyManagementController'
}).
when('/dashboard', {
templateUrl: 'partials/dashboard.html',
controller: 'DashboardController'
}).
when('/pipelines', {
templateUrl: 'partials/pipelines.html',
controller: 'PipeLinesController'
}).
when('/preferences', {
templateUrl: 'partials/preferences.html',
controller: 'PreferencesController'
}).
when('/reports', {
templateUrl: 'partials/reports.html',
controller: 'ReportsController'
}).
when('/logout', {
templateUrl: 'partials/logout.html',
controller: 'LogoutController',
resolve: {
logout: function (logout, $q) {
var deferred = $q.defer();
logout()['finally'](
function() {
deferred.resolve();
}
);
return deferred.promise;
}
}
}).
when('/privacy', {
templateUrl: 'partials/privacy.html',
controller: 'PrivacyController'
}).
when('/tos', {
templateUrl: 'partials/tos.html',
controller: 'TosController'
}).
when('/currentStatus', {
templateUrl: 'partials/currentStatus.html',
controller: 'CurrentStatusController'
}).
otherwise({
redirectTo: '/dashboard'
});
} else {
/**
* If user is not logged default action is
* home.
*/
$routeProvider.
when('/home', {
templateUrl: 'partials/home.html',
controller: 'HomeController'
}).
when('/resetpassword/:hashValue', {
templateUrl: 'partials/home.html',
controller: 'ResetPasswordController'
}).
when('/privacy', {
templateUrl: 'partials/privacy.html',
controller: 'PrivacyController'
}).
when('/tos', {
templateUrl: 'partials/tos.html',
controller: 'TosController'
}).
when('/currentStatus', {
templateUrl: 'partials/currentStatus.html',
controller: 'CurrentStatusController'
}).
otherwise({
redirectTo: '/home'
});
}
}]);
angular.bootstrap(document, ['appName']);
});
angular.element(document).ready(function() {
var injector = angular.injector(['appName']);
var settings = injector.get('settings');
var $http = injector.get('$http');
var functionFactory = function (userStatus) {
return function () {
this.lUserStatus = userStatus;
return this.lUserStatus;
}
};
/**
* So here we will check if user is logged or
* not and after this construct conditional routing
* into config method (above).
*/
$http.get(settings.apiUri + settings.loginStatus).
success(function (data) {
if(angular.isDefined(data.status) &&
data.status == "NOT_AUTHENTICATED") {
appName.service('userIsLogged', functionFactory(false));
angular.element(document).trigger("userStatusIsCheked", [false]);
} else if(angular.isDefined(data.status) && data.
status == "AUTHENTICATED") {
appName.service('userIsLogged',
functionFactory(true));
angular.element(document).trigger("userStatusIsCheked", [true]);
}
});
});
Hope this helps someone with a similar problem.