Makes 2 states share a part of resolve - javascript

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'
})
}])

Related

UI Router nested views

I've tried with various anwsers without any luck.
I have this two ui-views:
<div ui-view class="expand"></div> //Inside index.html
<div ui-view></div> //Inside home.html
And this is my routing:
$stateProvider
.state('home', {
url: '/',
views: {
'#': {
templateUrl: 'app/components/home/home.html',
controller: 'HomeCtrl'
}
}
})
.state('clients', {
url: '/clients',
views: {
'#home': {
templateUrl: 'app/components/clients/clients.html',
controller: 'ClientsCtrl'
}
}
})
I've tried putting names on the view and calling them in different ways but clients.html never gets display even though the route url changes.
I'm not entirely familiar with the view syntax that you're using with $stateProvider. I'll give you two versions, the first will seem very similar to your example and the second is more aligned with best practices.
$stateProvider
.state('base', {
abstract: true,
url: '',
templateUrl: 'views/base.html'
})
.state('login', {
url: '/login',
parent: 'base',
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
})
.state('dashboard', {
url: '/dashboard',
parent: 'base',
templateUrl: 'views/dashboard.html'
})
Best practice version:
(function () {
'use strict';
angular
.module('app.core')
.config(stateConfig)
.run(errorHandler);
stateConfig.$inject = ['$stateProvider', '$urlRouterProvider', '$locationProvider'];
getZipCodes.$inject = ['googleMapService'];
errorHandler.$inject = ['$rootScope', 'logger'];
function stateConfig($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/');
$stateProvider.state('core', {
url: '/',
templateUrl: 'app/core/core.html',
controller: 'CoreController',
controllerAs: 'vm',
resolve: {
getZipCodes : getZipCodes
}
})
}
/** #desc: Ping the back-end for a JSON object that will be converted into an array of NYC zip codes */
function getZipCodes(googleMapService) {
return googleMapService.getZipCodes();
}
/** #desc: $stateChangeError handler */
function errorHandler($rootScope, logger) {
$rootScope.$on('$stateChangeError', function (error, event) {
if (error) { logger.error('Error while changing states', error); }
if (event) { logger.error('The event that caused the error', event); }
})
}
})();

AngularJS ui-router: access child scope variables

I have such routes:
.config(function config($stateProvider) {
$stateProvider.state('articles', {
url: '/articles',
views: {
main: {
controller: 'ArticlesCtrl',
templateUrl: 'actions/articles/articles.html'
}
}
})
.state('articles.edit', {
url: '/upd/:itemId',
views: {
'': {
templateUrl: 'actions/articles/articles.edit.html',
controller: 'ArticlesEditCtrl',
}
}
})
.state('articles.add', {
url: '/add/news/',
views: {
'': {
templateUrl: 'actions/articles/articles.add.html',
controller: 'ArticlesAddCtrl',
}
}
})
})
and i'm updating some data in articles state, how can i force child controller with state articles.edit to update it's $scope.someVar with data from first state controller, without using services? Which way of solving this issue it the best one?
Since controller functions are 'newed' objects you could use the prototype of controllers to pass data around through an object like this
var obj = {}
function ArticlesCtrl($scope){
obj.ArticlesCtrl = ArticlesCtrl.prototype
ArticlesCtrl.prototype.passData = function(data){
//...do stuff with data passed from ArticlesEditCtrl
}
}
function ArticlesEditCtrl(){
obj.ArticlesCtrl.passData('some data here')
}
.config(function config($stateProvider) {
$stateProvider.state('articles', {
url: '/articles',
views: {
main: {
controller: 'ArticlesCtrl',
templateUrl: 'actions/articles/articles.html'
}
}
})
.state('articles.edit', {
url: '/upd/:itemId',
views: {
'': {
templateUrl: 'actions/articles/articles.edit.html',
controller: 'ArticlesEditCtrl',
}
}
})
.state('articles.add', {
url: '/add/news/',
views: {
'': {
templateUrl: 'actions/articles/articles.add.html',
controller: 'ArticlesAddCtrl',
}
}
})
})
put your function resolve just like that
$stateProvider.state('articles', {
url: '/articles',
views: {
main: {
controller: 'ArticlesCtrl',
templateUrl: 'actions/articles/articles.html'
}resolve: {
time: function AnyFunction(SessionTimer)
{
SessionTimer.startTimer();
}
}

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?

Possible to dynamically load controllers in Angular

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.

How to config Angular ui-router to not use strict URL matching mode

ui-router's version 0.2.11 introduced option to turn off strict URL matching, but I can't figure out how to actually use it.
I've tried standard config as they use in tests:
app.config(function ($urlMatcherFactoryProvider) {
$urlMatcherFactoryProvider.caseInsensitive(true);
$urlMatcherFactoryProvider.strictMode(false);
});
None of those settings work, so I guess I'm either doing something wrong or it's bugged. There's also seem to be no documentation about it.
I believe this was fixed in 0.2.12.
That said, I ran into this problem in 0.2.15. It turns out that you need to configure the $urlMatcherFactoryProvider BEFORE the $stateProvider.
i.e. the following code will NOT work:
$stateProvider.state('login', {
url: "/login",
templateUrl: 'templates/login.html',
controller: 'loginController as loginCtrl'
});
$urlMatcherFactoryProvider.caseInsensitive(true);
$urlMatcherFactoryProvider.strictMode(false);
You have to configure the $urlMatcherFactoryProvider first, like this:
$urlMatcherFactoryProvider.caseInsensitive(true);
$urlMatcherFactoryProvider.strictMode(false);
$stateProvider.state('login', {
url: "/login",
templateUrl: 'templates/login.html',
controller: 'loginController as loginCtrl'
});
use like this
app.config(["$routeProvider", "$locationProvider",
function ($routeProvider, $locationProvider) {
return $routeProvider.when("/", {
redirectTo: "/signin"
})
.when("/dashboard", {
templateUrl: "App/views/Dashboard/dashboard.html",
}).when("/signup", {
templateUrl: "App/views/signup/signup.html",
resolve: {
permission: function (authorizationService, $route) {
return authorizationService.permissionCheck("signup");
},
}
})
.when("/myAccount", {
templateUrl: "App/views/myAccount/myAccount.html",
resolve: {
permission: function (authorizationService, $route) {
return authorizationService.permissionCheck("myAccount");
},
}
})
.when("/signin", {
templateUrl: "App/views/signin/signin.html",
resolve: {
permission: function (authorizationService, $route) {
return authorizationService.permissionCheck("SKIP");
},
}
})

Categories