AngularJS - Calling abstract state not working - angularjs

I want use nested views in AngularJS 1.6, with UI-router.
I have 3 states, the first is an abstract view named settings, and the second and the third are two views.
.state('settings', {
url: '/settings',
abstract: true,
template: '<ui-view />'
})
.state('settings.account', {
url: '/account',
templateUrl: './partials/settings/account.html',
resolve: {
loginRequired: loginRequired
}
})
.state('settings.password', {
url: '/password',
templateUrl: './partials/settings/password.html',
resolve: {
loginRequired: loginRequired
}
})
The problem is that nothing appears when I go to settings/account or settings/password...

Related

Ui router URL bug

It doesn't work with the last one where there are three states. How do I make it work?
There is no error. The page itself doesn't load (It`s like I press link and nothing changes (except url in browser address line) )
.state('parent', {
url: '/home',
abstract: true,
template: '<ui-view/>'
})
.state('parent.index', {
url: '/index',
template: '<h1>test1</h1>'
})
.state('parent.contact', {
url: '/contact',
template: '<h1>test2</h1>'
})
.state('parent.contact.test', {
url: '/test',
template: '<h1>test3</h1>'
})
Try for this,
To be short, contact states are children of parentstate, so they can't have access of Test view, because it's related to test state.
So you need to write :
.state('parent.contact.test', {
url: "/test",
views: {
'Test#test' :{
templateUrl: "test.html"
}
}
})

Is there a way to have #/ and #/:param be separate states in UI-Router?

Problem:
When I navigate to #/ it tries to load the profile state which is at #/:userId.
So I'm completely perplexed by this functionality as it is seemingly intermittent. I already referred to this question and it seems that shuffling the order has no affect.
I want to have clean routes with UI-Router:
#/ This is the user's root dashboard
#/123 This is a specific user profile
#/my/preferences This is some other route.
$stateProvider
.state('profile', {
abstract: true,
url: '/:userId',
templateUrl: 'profile-user.html',
controller: 'ProfileController',
controllerAs: 'vm',
reloadOnSearch: false,
resolve: {
data: function() {
// some promises stuff
}
}
})
.state('profile.activity', {
url: '',
templateUrl: 'activity.html'
})
.state('dashboard', {
url: '/',
templateUrl: 'dashboard.html',
controller: 'DashboardController',
controllerAs: 'vm',
reloadOnSearch: false,
resolve: {
data: function() {
// some promises stuff
}
}
})
.state('preferences', {
url: '/my/preferences',
templateUrl: 'preferences.html',
controller: 'PreferencesController',
controllerAs: 'vm',
reloadOnSearch: false,
resolve: {
data: function() {
// some promises stuff
}
}
})
Question:
Is there a way to have #/, #/:param and #/someRoute/:someId be different states in UI-Router? Also, is there a way to see what routes are registered and in what order in UI-Router? That would be tremendously helpful during debugging.
The order is essential when UI-Router tries to resolve states. So define more specific state should be defined sooner then generic states:
// the specific will be checked first
.state('dashboard', {
url: '/',
...
.state('preferences', {
url: '/my/preferences',
...
// these will be used if above not matched
.state('profile', {
abstract: true,
url: '/:userId',
...

Issues with nested views using ui-router

The issue I'm having is that for some reason when navigating to the users home aside from it not loading and causing my browser to freeze when I inspect the console. (I take out the abstract: true from app.user) in the console it shows the 's of my of app.user.base nested inside each other with the top being the mainview and the footer getting loading inside of it. What Am i doing wrong?
.state('app', {
abstract: true,
url: '',
template: '<ui-view/>'
})
.state('app.user', {
abstract: true,
url: '/user',
templateURL: 'app/user/user.html'
})
.state('app.user.base, {
url: '',
views: {
mainView: {
template: '<ui-view/>'
}
footer: {
templateUrl: 'app/user/views/footer.html',
controller: 'footerCtrl'
}
}
})
.state('app.user.base.home', {
url: '/home',
templateURL: 'app/user/views/home.html',
controller: 'uHomeCtrl'
})
.state('app.user.base.profile', {
url: '/profile',
templateURL: 'app/user/views/profile.html',
controller: 'uProfileCtrl'
})
.state('app.main, {
abstract: true,
url: '',
templateURL: 'app/main/main.html'
})
.state('app.main.home, {
url: '/home',
views: {
landing: {
templateUrl: 'app/main/views/landing.html',
controller: 'landingCtrl'
},
about: {
templateUrl: 'app/main/views/about.html',
controller: 'aboutCtrl'
}
}
})
not sure if you can have it the same url's '/home' in few places, please read this article about nested states I may help to fix you issue.
You need to make sure to remove url property from all the states you have that are not navigable. Do that first, then see what new errors you get. URLs are not at all required to be able to navigate to a state.

Yet another issue with 'Could not resolve state to state'

I am using ui-router and my states are:
$stateProvider.state('app', {
url: "/app",
templateUrl: "assets/views/app.html",
abstract: true
}).state('app.dashboard', {
url: "/dashboard",
templateUrl: "assets/views/pages_timeline.html",
title: 'Dashboard',
controller: 'TimelineCtrl'
}).state('app.user.services', {
url: "/user/services",
templateUrl: "assets/views/user_services.html",
title: 'Service Integrations'
})
.state('login', {
url: '/login',
template: '<div ui-view class="fade-in-right-big smooth"></div>',
abstract: true
}).state('login.signin', {
url: '/signin',
templateUrl: "assets/views/login_login.html",
controller: 'AuthenticationCtrl'
}).state('login.forgot', {
url: '/forgot',
templateUrl: "assets/views/login_forgot.html"
}).state('login.registration', {
url: '/registration',
templateUrl: "assets/views/login_registration.html"
})
I am currently in the app.dashboard state, and I have a link:
<a ui-sref="app.user.services">
Service Integrations
</a>
However, when I click it, I get an error: Error: Could not resolve 'app.user.services' from state 'app'
What am I doing wrong?
The dot . notation is used to specify a parent relationship in ui-router, so the parent of state dashboard is state app.
With app.user.services there is no parent state app.user. So you need to define it (you can make it abstract):
.state("app.user", {
abstract: true,
template: "<div ui-view></div>"
})

angular ui router state - multiple states with same template and controller

I have states defined as below in my angularjs app using angular ui router state provider. And, I would like to define multiple states with the same configuration ie. with the same template and controller.
$stateProvider
.state('parent', {
templateUrl: 'parent.html',
abstract: true,
parent: 'apm'
})
.state('parent.list', {
abstract: true,
url: '/list',
templateUrl: 'list.html',
controller: 'ListCtrl'
})
.state('parent.list.closed', {
url: '/q',
templateUrl: 'closed.html'
})
.state('parent.list.details', { // would like to have same template, controller on different state parent.details without list
url: '/:id/:name',
abstract: true,
templateUrl: 'details.html',
controller: 'DetailsCtrl',
resolve: {
.....
.....
}
})
.state('parent.list.details.data', { // would like to have same template, controller on different state parent.details.data without list
url: '/details',
views : {
'view1' : {
templateUrl : 'view1.html'
},
'view2' : {
templateUrl : 'view2.html',
controller : 'View2Ctrl'
},
'view3' : {
templateUrl : 'view3.html'
},
'view4' : {
templateUrl : 'view4.html'
}
}
})
Is it possible to do something like
.state(['parent.list.details', 'parent.details'], {
url: '/:id/:name',
abstract: true,
templateUrl: 'details.html',
controller: 'DetailsCtrl',
resolve: {
.....
.....
}
})
Any help or suggestions?
Each state needs to be defined in it's own .state() method. You will run into multiple problems trying to do it the way you listed above. Most importantly would be the url.
You can simply do this:
.state('parent.list', {
url: '/list',
abstract: true,
templateUrl: 'details.html',
controller: 'DetailsCtrl',
resolve: {
.....
.....
}
.state('parent.list.details', {
url: '/:id/:name',
abstract: true,
templateUrl: 'details.html',
controller: 'DetailsCtrl',
resolve: {
.....
.....
}
})
While the code is not condensed or efficient in the sense you have to declare the controller and partial used on each state, it is necessary because each state needs its own .state() method
I wanted the same and made it like this:
//add a new Function to the object $stateProvider
$stateProvider.states = (statesArr, obj) => {
for (var i in statesArr) {
var state = statesArr[i];
$stateProvider.state(state, obj);
}
return $stateProvider;
};
//use the new function
$stateProvider
.states(["main", "main.test"], {
url: '/main',
templateUrl: 'modules/ViewContainer.html',
controllerAs: 'currentCtrl',
controller: 'MainCtrl'
})

Resources