I am having an issue with ui router where the state is not being triggered on a url.
On navigation to /#/dashboard/ the $state.current is set to abstract true with no state selected within.
No error messages are being thrown on $stateChangeError
JS -
var app = angular.module('frame', ['ui.router']);
app.config(['$stateProvider', '$locationProvider', function($stateProvider, $locationProvider) {
$stateProvider
.state('dashboard', {
url: '/dashboard/',
views: {
'header#': {
template: 'header'
},
'nav#': {
template: 'nav'
},
'main#': {
template: 'main'
}
}
});
// $locationProvider.html5Mode(true);
}]).
run(['$browser', '$rootScope', '$state', function($browser, $rootScope, $state){
// $browser.baseHref = function() { return '../'; };
$rootScope.$on("$stateChangeError", console.log.bind(console));
console.log(window.location);
$rootScope.state = $state;
}]);
html -
<body>
<div ui-view="header">
</div>
<nav ui-view="nav">
</nav>
<main ui-view="main">
</main>
</body>
Here is a link that throughly explains how to use Absolute Names,
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
Related
I have the following app.js file:
'use strict';
var app = angular.module('app', [
'auth0',
'angular-storage',
'angular-jwt',
'ui.router',
'Environment',
'Api',
'Profile'
]);
app.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'js/modules/App/views/frontpage.html'
})
.state('login', {
url: '/login',
templateUrl: 'js/modules/User/views/login.html',
controller: 'LoginCtrl'
});
$urlRouterProvider
.otherwise('/main');
}]);
app.config(['authProvider', '$httpProvider', '$locationProvider', 'jwtInterceptorProvider',
function myAppConfig(authProvider, $httpProvider, $locationProvider, jwtInterceptorProvider) {
authProvider.init({
domain: 'marcrasmussen.eu.auth0.com',
clientID: 'hphpe4JiceMW8FSA02CN7yOYl5fUaULe',
loginUrl: '/login'
});
authProvider.on('loginSuccess', ['$location', 'profilePromise', 'idToken', 'store',
function ($location, profilePromise, idToken, store) {
console.log("Login Success");
profilePromise.then(function (profile) {
store.set('profile', profile);
store.set('token', idToken);
});
$location.path('/');
}]);
//Called when login fails
authProvider.on('loginFailure', function () {
alert("Error");
});
//Angular HTTP Interceptor function
jwtInterceptorProvider.tokenGetter = ['store', function (store) {
return store.get('token');
}];
//Push interceptor function to $httpProvider's interceptors
$httpProvider.interceptors.push('jwtInterceptor');
}]);
app.run(['auth', function (auth) {
// This hooks all auth events to check everything as soon as the app starts
auth.hookEvents();
}]);
And i have the following profile.js file:
angular.module('Profile', [])
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('profile', {
abstract: true,
url: '/profile'
})
.state('profile.index', {
url: '/index',
templateUrl: 'js/modules/Profile/views/viewProfile.html'
})
}]);
in my index.html the files are listed as such:
<script src="js/modules/Profile/lib/profile.js"></script>
<script src="js/modules/App/lib/app.js"></script>
<script src="js/modules/App/directives/login/login.js"></script>
And lastly ofcourse i have my view port:
<div class="main" ui-view>
</div>
As you can tell my application starts on the route /main this works perfectly fine and frontpage.html is being rendered with all the html inside that file.
However when i go to profile.index or /profile/index no error is displayed in the console and no html within the template file js/modules/Profile/views/viewProfile.html is displayed.
Can anyone tell me why this is happening? what am i doing wrong?
I think the issue may be your abstract state. You are not defining a template or templateUrl for this state. Also note that the template for your abstract state must include a ui-view directive in order for its children to populate.
https://github.com/angular-ui/ui-router/wiki/nested-states-%26-nested-views#abstract-state-usage-examples
You may need to do something along the lines of:
.state('profile', {
abstract: true,
url: '/profile',
template: '<ui-view />
})
I want to show tab(profile+setting), like the following image, but when i click on any tabs, corresponding template is not loading. In customerinfo.view.html I tried to change <div ui-view="{{tab.view}}"></div> to <div ui-view></div> it causing me infinite digest cycle.
I am able to change the url, When first time we hit the url http://localhost:3000/home/#/updatecustomer/3/ following time opens, when click on profile, url change to http://localhost:3000/home/#/updatecustomer/3/profile, but corresponding template(profile.html) is not loading, same is happening for setting
I go through this stackoverflow question, but no help
Module definition
(function() {
'use strict';
var app = angular.module('app', ['ui.router', 'ngCookies', 'ui.bootstrap']);
app.config(function config($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', {
url: '/',
controller: 'HomeController',
templateUrl: 'home/home.view.html',
})
.state('home.updatecustomer', {
url: 'updatecustomer/:customerId/',
controller: 'TabsDemoCtrl',
templateUrl: 'addcustomer/customerinfo.view.html',
})
.state('home.updatecustomer.profile', {
url: 'profile',
controller: 'ProfileCtrl',
templateUrl: 'addcustomer/profile.html',
}))
.state('home.updatecustomer.setting', {
url: 'setting',
controller: 'SettingCtrl',
templateUrl: 'addcustomer/setting.html',
})
customer.js
(function () {
'use strict';
var app = angular.module('app');
app.controller('TabsDemoCtrl', TabsDemoCtrl);
TabsDemoCtrl.$inject = ['$scope', '$state'];
function TabsDemoCtrl($scope, $state){
$scope.customer = 3;
$scope.tabs = [
{ title:'profile', view:'profile', active:true },
{ title:'setting', view:'setting', active:false }
];
}
})();
customerinfo.view.html
<uib-tabset active="active">
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disable="tab.disabled">
<div ui-view="{{tab.view}}"></div>
</uib-tab>
</uib-tabset>
profile.js
(function () {
'use strict';
var app = angular.module('app') ;
app.controller('ProfileCtrl', ProfileCtrl);
ProfileCtrl.$inject = ['$scope'];
function ProfileCtrl($scope){
$scope.profile="Profile 123";
}
})() ;
profile.html
profile
Setting.js
(function () {
'use strict';
var app = angular.module('app') ;
app.controller('SettingCtrl', SettingCtrl);
SettingCtrl.$inject = ['$scope'];
function SettingCtrl($scope){
$scope.setting="setting 1213";
}
})() ;
setting.html
setting
Edit:
1) The first thing-- the naming of your urls. Instead of http://localhost:3000/home/#/updatecustomer/3/ the url should be http://localhost:3000/#/updatecustomer/3/
2) You want the tabs to be children of your home state. Do this by setting abstract: true.
$stateProvider
.state('home', {
abstract: true,
controller: 'HomeController',
templateUrl: 'home/home.view.html'
})
3) The url for your routes must begin with a /.
.state('home.your-splash-view', {
url: '/home',
controller: 'HomeCtrl',
templateUrl: 'home/splash.view.html'
})
.state('home.updatecustomer', {
url: '/updatecustomer/:customerId/',
controller: 'TabsDemoCtrl',
templateUrl: 'addcustomer/customerinfo.view.html'
})
.state('home.updatecustomer.profile', {
url: '/profile',
controller: 'ProfileCtrl',
templateUrl: 'addcustomer/profile.html'
});
4) Consider navigating states with theui-sref directive.
Something like:
<uib-tab ui-sref='home.updatecustomer.profile'> ... </ui-tab>
Related:
what is the purpose of use abstract state?
Why give an "abstract: true" state a url?
I've been following this tutorial https://www.youtube.com/watch?v=X_NZr_-RaLw and in my clientapp.js, when I insert
.factory('UserService', function($resource) {
return $resource('https://troop.tech/api/users/:user', {user: '#user'});
});
Into my code, all the angular UI routing just stops working.
Context:
var myApp = angular.module('myApp', ['ui.router','ngRouter'])
myApp.factory('UserService', function($resource) {
return $resource('https://troop.tech/api/users/:user', {user: '#user'});
});
myApp.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
$urlRouterProvider.otherwise('/dashboard');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'partial-home.html'
})
.state('dashboard', {
url: '/dashboard',
templateUrl: 'partial-dashboard.html'
})
.state('about', {
url: '/about',
templateUrl: 'partial-about.html'
})
.state('register', {
url: '/register',
templateUrl: 'partial-register.html'
});
$httpProvider.interceptors.push('authInterceptor');
});
myApp.controller('userController', function ($scope, $http, $window, UserService) {
$scope.users = UserService.query();
$scope.setDataForUser = function(userID) {
};
$scope.addUser = function(){
};
...
In your factroy you use $resource as a parameter so you need inject angular built in resource liberary.
In index.html:
<script src="yourComponentFolder/angular-resource/angular-resource.js"></script>
And add a module ngResource...
var myApp = angular.module('myApp', ['ui.router','ngRouter','ngResource']);
Reference in your Application that yoy follow
And one thing if you use ui-router not necessary to inject ngRouter so if you can discard ngRouter from module.
I am having an issue where once the templateUrl is added into the ui-router child state, the application will no longer perform the routing to the state. It works fine when it's just a template.
app.js:
app.config(['$stateProvider', '$locationProvider', '$urlMatcherFactoryProvider', '$urlRouterProvider',
function ($stateProvider, $locationProvider, $urlMatcherFactoryProvider, $urlRouterProvider) {
$urlMatcherFactoryProvider.caseInsensitive(true);
$urlMatcherFactoryProvider.strictMode(false);
$urlRouterProvider.otherwise('/page-not-found');
$stateProvider
.state('dashboard', {
url: '/',
views: {
'header': {
template: 'header'
},
'nav': {
template: 'nav'
},
main: {
template: 'You are on the homepage'
}
}
});
$locationProvider.html5Mode(true);
}]);
app.run(['$rootScope', 'userService', '$state', function ($rootScope, user, $state) {
$rootScope.$on("$stateChangeError", console.log.bind(console));
if (!user.exists) {
$state.go('user.reg');
}
}]);
User.states.js:
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('user', {
url: '/users',
abstract: true,
views: {
'header': {},
'nav': {},
'main': {
template: '<ui-view/>'
}
}
})
.state('user.reg', {
url: '/register',
//template: 'This will show fine',
templateUrl: '/app/Users/User.login.html' // this will break
});
}]);
UPDATE
If I add a ui-sref="user.reg" to my initial pages I can navigate to the state/page fine, with the templateUrl and template . So its just an issue when I try to use state.go('user.reg');
This means a work around is using the $location provider to change the path. Has the same effect but does seem rather wrong
The problem is with your relative paths.
Look at this code:
$locationProvider.html5Mode(true);
You have html5 mode enabled, and for that to work, you have your base ref set in your html, which probably looks like this:
<base href="/">
Your issue is likely that the route for your template isn't "yoursite.com/app/Users/User.login.html."
See this Plunker for a working version of your code. Then go into the html code and uncomment out the base tag, and notice that it will break.
I am trying to inject a resolve object with loaded data into my controller but I get an Unknown Provider error :
Unknown provider: configServiceProvider <- configService
Here is my code:
StateProvider
$stateProvider
.state('index', {
abstract: true,
url: "/index",
templateUrl: "#",
resolve: {
configService: function () {
return {
"helloText": "Welcome in Test Panel"
};
}
}
})
Controller
function MainCtrl($scope, configService) {
$scope.config = configService;
};
angular.module('dot', ['ui.router'])
.config(config)
.controller('MainCtrl', MainCtrl)
Snippet
function config($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("#");
$stateProvider
.state('index', {
abstract: true,
url: "/index",
templateUrl: "#",
resolve: {
configService: function() {
return {
"helloText": "Welcome in Test Panel"
};
}
}
})
};
function MainCtrl($scope, configService) {
$scope.config = configService;
};
(function() {
angular.module('dot', [
'ui.router', // Routing
])
.config(config)
.run(function($rootScope, $state) {
$rootScope.$state = $state;
})
.controller('MainCtrl', MainCtrl)
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.13/angular-ui-router.min.js"></script>
<div ng-app="dot">
<div ng-controller="MainCtrl as main">
<div ui-view>
</div>
</div>
</div>
It's like my resolve object is defined after my controller has loaded... I'm new to angularJS and I feel like I am definitely missing something very obvious.
Thanks.
The ng-controller and UI-Router state resolve are incompatible. That's why your "another-world" 'MainCtrl' cannot be injected with a resolve/service defined in UI-Router.
But there is a simple way, just convert it into state:
// brand new root state, providing root (index.html) stuff
// not effecting url or state names
.state('root', {
abstract: true,
template: '<div ui-view=""></div>', // a target for child state
resolve: {
configService: function () { // ready for any state in hierarchy
return {
"helloText": "Welcome in Test Panel"
};
}
},
// brand new line, with 'MainCtrl', which is part of UI-Router now
controller: 'MainCtrl',
})
The original root state 'index' will now be placed inside of a real, but abstract, url not effecting state - 'root'
// adjusted state
.state('index', { // will be injected into parent template
parent: 'root'
abstract: true,
url: "/index",
templateUrl: ...,
// resolve not needed, already done in root
//resolve: { }
})
Adjusted index.html
<div ng-app="dot">
<div ui-view="></div> // here will be injected root state, with 'MainCtrl'
//<div ng-controller="MainCtrl as main">
// <div ui-view>
// </div>
//</div>
</div>
Maybe also check - Nested states or views for layout with leftbar in ui-router?