Possible to dynamically load controllers in Angular - javascript

When I go to a specific view in my Angular project, every controller code is being load.
I understand that it's possible to prevent this. But is it possible in the following situation?
App.js config:
app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider',
function($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider) {
$httpProvider.interceptors.push('AuthInterceptor');
$stateProvider.state('home', {
url: "/home",
templateUrl: 'views/Home.html',
controller: "MainController",
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('challenge');
}
}]
}).state('login', {
url: '/login',
templateUrl: 'views/Login.html',
controller: 'UserCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('home');
} else {
//console.log("Niet ingelogd")
}
}]
}).state('register', {
url: '/register',
templateUrl: 'views/Register.html',
controller: 'UserCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('home');
}
}]
}).state('challenge', {
url: '/challenges',
templateUrl: 'views/Challenges.html',
controller: 'ChallengeCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}]
}).state('profile', {
url: '/profile',
templateUrl: 'views/Profile.html',
controller: "ProfileCtrl",
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}]
}).state('policy', {
url: '/policy',
templateUrl: 'views/Policy.html',
controller: 'AppCtrl'
}).state('cookie', {
url: '/cookie',
templateUrl: 'views/Cookie.html',
controller: 'AppCtrl'
}).state('challengesdone', {
url: '/challengesdone',
templateUrl: 'views/Challengesdone.html',
controller: 'ChallengesDoneCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}]
}).state('forgot', {
url: '/forgot',
templateUrl: 'views/Forgot.html',
controller: 'UserCtrl'
}).state('reset', {
url: '/reset?sptoken',
templateUrl: 'views/Reset.html',
controller: 'UserCtrl'
});
$urlRouterProvider.otherwise('home');
}]);
Can this be accomplished without the use of external libraries and are there alot of adjustments needed?

You need to use $controllerProvider in your config.
app._controller = app.controller
app.controller = function (name, constructor){
$controllerProvider.register(name, constructor);
return (this);
};
And then resolve this method in your route.
.state('reset', {
url: '/reset?sptoken',
controller: 'UserCtrl',
resolve: {
deps : function ($q, $rootScope) {
var deferred = $q.defer();
require(["js/userCtrl"], function (tt) {
$rootScope.$apply(function () {
deferred.resolve();
});
deferred.resolve()
});
return deferred.promise;
}
},
templateUrl: 'views/Reset.html'
});
I have put together a CodePen for your.

Related

Makes 2 states share a part of resolve

I have defined two states as follows:
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('edit', {
url: '/edit/{id}',
templateUrl: '/htmls/h1.html',
controller: 'SameCtrl',
onEnter: ...sameOnEnter...
resolve: {
...commonResolve...
}
})
.state('addinEdit', {
url: '/addin/edit/{id}',
templateUrl: '/htmls/h2.html',
controller: 'SameCtrl',
onEnter: ...sameOnEnter...
resolve: {
special: [ ... ],
...commonResolve...
}
})
}])
So they share the same controller, the same onEnter, and they have a very long and common part for resolve (which is actually a chain of resolves: first: function (...){...}, second: function (...){...}, ...). Does anyone know how to rewrite them so that I don't have to write commonResolve twice?
Just create a function for the resolver:
app.config(['$stateProvider', function ($stateProvider) {
resolverFunction.$inject = ['resolverA', 'resolverB'];
function ResolverFunction(myService1, myService2) {
return 'something';
}
resolverAFunction.$inject = ['resolverC'];
function resolverAFunction(resolverC) {
return 'anything';
}
resolverBFunction.$inject = ['resolverC'];
function resolverBFunction(resolverC) {
return 'something else';
}
resolverCFunction.$inject = ['service'];
function resolverCFunction(service) {
return 'something else';
}
$stateProvider
.state('edit', {
url: '/edit/{id}',
templateUrl: '/htmls/h1.html',
controller: 'SameCtrl',
onEnter: ...sameOnEnter...
resolve: {
commonResolver: resolverFunction,
resolverA: resolverAFunction,
resolverB: resolverBFunction,
resolverC: resolverCFunction,
}
})
.state('addinEdit', {
url: '/addin/edit/{id}',
templateUrl: '/htmls/h2.html',
controller: 'SameCtrl',
onEnter: ...sameOnEnter...
resolve: {
special: [ ... ],
commonResolver: resolverFunction,
resolverA: resolverAFunction,
resolverB: resolverBFunction,
resolverC: resolverCFunction,
}
})
}])
I don't have experience angularjs but i found a solution,
you can specify the parent of a state via the parent property.
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('edit', {
url: '/edit/{id}',
templateUrl: '/htmls/h1.html',
controller: 'SameCtrl',
onEnter: ...sameOnEnter...
resolve: {
...commonResolve...
}
})
.state('addinEdit', {
url: '/addin/edit/{id}',
templateUrl: '/htmls/h2.html',
parent : 'edit'
})
}])

Getting error while injecting $uibModal

I'm getting error when I try to inject $uibModal to my new state.
In other states it works properly. What can be the cause of the error?
Error log
Error: [$injector:unpr] http://errors.angularjs.org/1.5.7/$injector/unpr?p0=49d19463-4701-4df9-ba96-5053f03a665bProvider%20%3C-%2049d19463-4701-4df9-ba96-5053f03a665b
at angular.min.js:6
at angular.min.js:43
at Object.d [as get] (angular.min.js:40)
at angular.min.js:43
at Object.d [as get] (angular.min.js:40)
at ui-bootstrap-tpls.js:3656
at Object.r [as forEach] (angular.min.js:8)
at Object.resolve (ui-bootstrap-tpls.js:3652)
at Object.$modal.open (ui-bootstrap-tpls.js:4256)
at b.$scope.showNotification (NotificationsController.js:19)
My controller
angular.module('EProc.Notifications')
.controller('notificationsCtrl', ['$scope', '$http', '$uibModal',
function($scope, $http, $uibModal){
$http.get('/api/notification/lastmsg').then(function(result) {
console.log('last 10 notifications--------------------');
console.log(result);
$scope.lastNotifications = result.data.content;
$scope.newMessages = result.data.newMessages;
});
$http.get('/api/notification/messages').then(function(result) {
console.log('all notifications--------------------');
console.log(result);
$scope.allNotifications = result.data.content;
});
$scope.showNotification = function(id) {
$uibModal.open({
animation: true,
size: 'md',
templateUrl: 'client/components/notifications/tmpl/notificationModal.html',
controller: 'notificationModalCtrl',
resolve: {
id: id
}
});
}
}
])
.controller('notificationModalCtrl', ['$scope', 'id', '$uibModalInstance',
function($scope, id, $uibModalInstance){
$http.get('/api/notification/message/' + id).then(function(result) {
$scope.notification = result.data;
})
}]);
mainApp.js
var eProcApp = angular.module('EProc',
[
'ui.router',
'ui.bootstrap',
'smart-table',
'ngTagsInput',
'EProc.Common',
'EProc.Profile',
'EProc.Purchasers',
'EProc.Supply',
'EProc.Tenders',
'EProc.Notifications'
]);
eProcApp.config(['$stateProvider', '$httpProvider', '$urlRouterProvider',
function ($stateProvider, $httpProvider, $urlRouterProvider) {
$stateProvider
.state('myprofile', {
url: '/myprofile',
templateUrl: 'client/components/profile/tmpl/profileShortDetails.html',
controller: 'profileDetailsCtrl'
})
.state('main', {
url: '/main',
views: {
'': {
templateUrl: 'client/components/purchase/tmpl/annualPlans.html'
},
'itemstable#main': {
templateUrl: 'client/components/purchase/tmpl/procurementPlan.html',
controller: 'annualProcPlanCtrl'
}
}
})
.state('purchasers', {
url: '/purchasers/:purchaserId',
views: {
'': {
templateUrl: 'client/components/purchase/tmpl/purchasers.html',
controller: 'purchasersListCtrl'
}
}
})
.state('purchasers.procplan', {
url: "/procplan",
templateUrl: 'client/components/purchase/tmpl/procurementPlan.html',
controller: 'procurementPlanCtrl'
})
.state('purchasers.children', {
url: "/children",
templateUrl: 'client/components/purchase/tmpl/childrenPartiesList.html',
controller: 'childrenPurchasersCtrl'
})
.state('procplan', {
url: '/procplan/:purchaserId',
views: {
'': {
templateUrl: 'client/components/purchase/tmpl/procurementPlan.html',
controller: 'procurementPlanCtrl'
}
}
})
.state('procitem', {
url: '/procitem/:itemId',
templateUrl: 'client/components/purchase/tmpl/procurementItem.html',
controller: 'procurementItemCtrl'
})
.state('search', {
url: '/procitem/search/:page?searchText',
params: {'filter': {}},
views: {
'': {
templateUrl: 'client/components/purchase/tmpl/searchProcItems.html',
controller: 'searchProcItemsCtrl'
},
'search-results#search': {
templateUrl: 'client/components/purchase/tmpl/search/resultsSectionsView.html',
controller: 'procItemSearchResultsCtrl'
}
}
})
.state('favgroups', {
url: '/favgroups',
templateUrl: 'client/components/supply/tmpl/favoriteGroups.html',
controller: 'favoriteGroupsCtrl'
})
.state('favorites', {
url: '/favorites/:gswId',
templateUrl: 'client/components/supply/tmpl/favoritesList.html',
controller: 'favoritesListCtrl'
})
.state('proposals', {
url: '/proposals',
templateUrl: 'client/components/supply/tmpl/commProposalsList.html',
controller: 'commProposalListCtrl'
})
.state('proposal', {
url: '/proposal/:procItemId',
templateUrl: 'client/components/supply/tmpl/commProposal.html',
controller: 'commProposalCtrl'
})
.state('tenders', {
url: '/tenders/',
templateUrl: 'client/components/tenders/tmpl/tendersList.html',
controller: 'tendersListCtrl'
})
.state('announcement', {
url: '/announcement/:announcementId',
templateUrl: 'client/components/tenders/tmpl/singleAnnouncementView.html',
controller: 'viewAnnouncementCtrl'
})
.state('watchlist', {
url: '/watchlist/',
templateUrl: 'client/components/supply/tmpl/keywordMatchWatchList.html',
controller: 'kwMatchWatchListCtrl'
})
.state('notifications', {
url: '/notifications',
templateUrl: 'client/components/notifications/tmpl/notifications.html',
controller: 'notificationsCtrl'
});
$httpProvider.interceptors.push('loginInterceptor');
}]);
The resolve property values must be functions, ie
resolve: {
id: function() { return id }
}

How to write $routeProvider.whenLoggedIn function in common place for all modules

I have a config function in each module file like below
in app.js
config(['$locationProvider', '$routeProvider',
function($locationProvider, $routeProvider) {
$routeProvider.otherwise({redirectTo: '/home'});
}]);
in home.js
config(['$routeProvider','ChartJsProvider',
function ($routeProvider,ChartJsProvider) {
$routeProvider.when('/home', {
templateUrl: 'home/home.html',
controller: 'HomeCtrl'
});
}])
now I want to write a $routeProvider.whenLoggedIn function like
config(['$locationProvider', '$routeProvider',
function($locationProvider, $routeProvider) {
$routeProvider.whenLoggedIn=function(){
console.log('Do something');
}
$routeProvider.otherwise({redirectTo: '/home'});
}]);
when I wrote code like code below
$routeProvider.whenLoggedIn('/profile', {
templateUrl: 'home/profile.html',
controller: 'ProfileCtrl'
});
I want to call the function whenLoggedIn. Please let me know how to write whenLoggedIn function in common place instead writing this function in every module config function
You need to add $stateProvider in app.config
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
//$locationProvider.html5Mode(true).hashPrefix('*');
$urlRouterProvider.otherwise('/account/login');
$stateProvider
.state('account', {
abstract: true,
url: '/account',
cache: false,
template: '<div ui-view></div>',
})
//login
.state('account.login', {
url: '/login',
controller: 'LoginCtrl',
templateUrl: 'app/Account/login.html',
})
//forgot password
.state('account.forgotpassword', {
url: '/forgotpassword',
controller: 'ForgotPswdCtrl',
templateUrl: 'app/Account/forgotpassword.html',
})
}])

angularjs - backspace is not working

I have a problem when i click on backspace
it doesn't go to the last page
i don't know how to fix it sometime it does go the last page only when i go from app.home page to app.newJob.Step1 and press backspace it goes back to home but not always
here is my router
'use strict';
angular.module('ijob').
config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'Views/login.html',
data: {
requireLogin: false
}
})
.state('app', {
abstract: true,
template: '<ui-view/>',
data: {
requireLogin: true
}
})
.state('app.home', {
url: '/home',
templateUrl: '/Views/home.html'
})
.state('app.editJob', {
url: '/editJob',
templateUrl: 'Views/editJob.html'
})
.state('app.purchasePackages', {
url: '/purchasePackages',
templateUrl: 'Views/purchasePackages.html'
})
.state('app.accountDetails', {
url: '/accountDetails',
templateUrl: 'Views/accountDetails.html'
})
.state('app.jobOrder2', {
url: '/jobOrder2',
templateUrl: 'Views/jobOrder2.html'
})
.state('app.newJob', {
abstract: true,
templateUrl: 'Views/newJob/newJob.html',
url: '/newJob'
})
.state('app.newJob.Step1', {
url: '/newJob/step1',
templateUrl: 'Views/newJob/step1.html'
})
.state('app.newJob.Step2', {
url: '/newJob/step2',
templateUrl: 'Views/newJob/step2.html'
})
.state('app.newJob.Step3', {
url: '/newJob/step3',
templateUrl: 'Views/newJob/step3.html'
})
.state('app.newJob.Step4', {
url: '/newJob/step4',
templateUrl: 'Views/newJob/step4.html'
})
.state('app.newJob.Step5', {
url: '/newJob/step5',
templateUrl: 'Views/newJob/step5.html'
});
$urlRouterProvider.otherwise('/home');
// $locationProvider.html5Mode(true);
})
.config(function config() {
});
and my app
'use strict';
// Declare app level module which depends on views, and components
angular.module('ijob', [
'ui.router', 'ngRoute', 'btorfs.multiselect', 'ngCookies', 'ngResource'
]);
var app = angular.module('ijob');
app.run(['$state', '$cookieStore', '$rootScope', 'Auth', 'UserService',
function ($state, $cookieStore, $rootScope, auth, userService) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
var requireLogin = toState.data.requireLogin;
if (requireLogin && !($cookieStore.get('authdata'))) {
event.preventDefault();
$state.go('login');
}
else if ($cookieStore.get('authdata') && $state.current.name !== toState.name) {
userService.token = auth.getCredentials($cookieStore.get('authdata'));
console.log(userService);
$state.current.name = toState.name;
$state.go(toState.name);
}
});
}]);
sometimes i get that error
Error: No such state 'app.newJob.Step1'
or
Error: No such state 'login'
and the states do exist.
its something about the ui router?
or there is anyway to override that?

AngularJs with ui.router how to set authenticate for its children

i'am using AngularJS with ui-router, this is my current app.js configuration.
'use strict';
angular.module('nodeserverApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
'ui.bootstrap',
'ui.router'
])
.config(function ($routeProvider, $locationProvider, $httpProvider , $stateProvider , $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'partials/user/main',
controller: 'MainCtrl'
})
.state('dashboard', {
url: '/user/dashboard',
templateUrl: 'partials/user/dashboard/main',
controller: 'UserDashboardDashboardCtrl',
authenticate: true
})
.state('dashboard.welcome', {
url: '/welcome',
parent: 'dashboard',
templateUrl: 'partials/user/dashboard/welcome'
})
.state('dashboard.account', {
url: '/account',
templateUrl: 'partials/user/dashboard/account',
controller: 'UserDashboardAccountCtrl'
})
.state('dashboard.address', {
url: '/address',
templateUrl: 'partials/user/dashboard/address/index'
})
.state('dashboard.address.view', {
url: '/view',
templateUrl: 'partials/user/dashboard/address/view',
controller: 'UserDashboardAddressViewCtrl'
})
.state('dashboard.address.new', {
url: '/new',
templateUrl: 'partials/user/dashboard/address/new',
controller: 'UserDashboardAddressNewCtrl'
})
.state('login', {
url: '/user/login',
templateUrl: 'partials/user/login',
controller: 'LoginCtrl'
})
.state('signup', {
url: '/user/signup',
templateUrl: 'partials/user/signup',
controller: 'SignupCtrl'
})
.state('settings', {
url: '/user/settings',
templateUrl: 'partials/user/settings',
controller: 'SettingsCtrl',
authenticate: true
});
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode(true);
// Intercept 401s and 403s and redirect you to login
$httpProvider.interceptors.push(['$q', '$location', function($q, $location) {
return {
'responseError': function(response) {
if(response.status === 401 || response.status === 403) {
$location.path('/user/login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
};
}]);
})
.run(function ($rootScope, $state, Auth) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){
if (toState.authenticate && !Auth.isLoggedIn()){
// User isn’t authenticated
$state.transitionTo("login");
event.preventDefault();
}
});
});
as you can see, dashboard requires authentication, how can i make it's children inherit the authenticate like dashboard.welcome , dashboard.address.view etc. with out the need to specify each one?
I know this is pretty old, but for future Googlers, note that the data property is inherited by child states, so you can place something like this authenticate flag in the parent. These modifications to your should do the trick:
For $stateProvider:
.state('dashboard', {
url: '/user/dashboard',
templateUrl: 'partials/user/dashboard/main',
controller: 'UserDashboardDashboardCtrl',
data: {
authenticate: true
}
})
For angular.module:
.run(function ($rootScope, $state, Auth) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){
if (toState.data.authenticate && !Auth.isLoggedIn()){
// User isn’t authenticated
$state.transitionTo("login");
event.preventDefault();
}
});
});
I hope this link will help, this is a great article from Frederik Nakstad about the Single Page Auth for AngularJS, sorry but not able to provide you the detail codes
http://frederiknakstad.com/2013/01/21/authentication-in-single-page-applications-with-angular-js/

Categories