Angular could not resolve from state - angularjs

I used jhipster to generate my app and I tried to add two different types of forms, that would both use same entity (one wouldn't use all fields in entity and other would use all).
Now, it works alright for:
.state('xyz', {
parent: 'entity',
url: '/xyz',
data: {
authorities: ['ROLE_USER'],
pageTitle: 'xyzs'
},
views: {
'content#': {
templateUrl: 'app/entities/xyz/xyzs.html',
controller: 'XyzController',
controllerAs: 'vm'
}
},
resolve: {
}
}).state('xyz.new', {
parent: 'xyz',
url: '/new',
data: {
authorities: ['ROLE_USER']
},
onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
$uibModal.open({
templateUrl: 'app/entities/xyz/xyz-dialog.html',
controller: 'XyzDialogController',
controllerAs: 'vm',
backdrop: 'static',
size: 'lg',
resolve: {
entity: function () {
return {
...
};
}
}
}).result.then(function() {
$state.go('xyz', null, { reload: true });
}, function() {
$state.go('xyz');
});
}]
})
And it works alright, but if I change it a small bit and use:
.state('xyz', {
parent: 'entity',
url: '/xyz',
data: {
authorities: ['ROLE_USER'],
pageTitle: 'xyzs'
},
views: {
'content#': {
templateUrl: 'app/entities/xyz/xyzs.html',
controller: 'XyzController',
controllerAs: 'vm'
}
},
resolve: {
}
}).state('a-xyz.new', {
parent: 'xyz',
url: '/a/new',
data: {
authorities: ['ROLE_USER']
},
onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
$uibModal.open({
templateUrl: 'app/entities/xyz/a-xyz-dialog.html',
controller: 'XyzDialogController',
controllerAs: 'vm',
backdrop: 'static',
size: 'lg',
resolve: {
entity: function () {
return {
...
};
}
}
}).result.then(function() {
$state.go('xyz', null, { reload: true });
}, function() {
$state.go('xyz');
});
}]
})
And I've change my
ui-sref="xyz.new"
to
ui-sref="a-xyz.new"
in my html template
I'm getting an error:
Error: Could not resolve 'a-xyz.new' from state 'xyz'
transitionTo#http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:3180:17
go#http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:3108:14
clickHook/</transition<#http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:4158:9
timeout/timeoutId<#http://localhost:9000/bower_components/angular/angular.js:19157:28
completeOutstandingRequest#http://localhost:9000/bower_components/angular/angular.js:5869:7
Browser/self.defer/timeoutId<#http://localhost:9000/bower_components/angular/angular.js:6145:7

The dot notation is basically used to indicate child state for a parent state. You may refer to this link for better understanding of nested views/states.
Nested Views
Go through this:
Why Parent State must exist
One parent can have multiple child states. So, if your parent state is 'xyz', you can multiple child states as 'xyz.a', 'xyz.b', 'xyz.c' etc.

Related

Angular UI Router Nested States with nested Views / Controllers

Trying to find a way to load both nested state views and controllers under a parent view and controller. I have it successfully routing, but it doesn't load the nested template or the controller.
Appreciate the help!
stateHelperProvider.state({
name: 'artist',
url: '/' + artistSlug,
abstract: true,
resolve: {
artist: ['appArtist', function(appArtist) {
return app.getArtist();
}]
},
children: [
{
name: 'events',
url: '/',
templateUrl: "/templates/events/events.html",
controller: "eventsCtrl",
parent: 'artist'
},
{
name: 'extra-info',
url: '/extra-info',
templateUrl: "/templates/extra-info.html",
parent: 'artist'
},
{
name: 'articles',
url: '/articles',
templateUrl: "/templates/articles/articles.html",
controller: "articlesCtrl",
parent: 'artist'
}
]
});
You can do it as follows:
var myApp = angular.module('angularApp', ['ui-router'])
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('artist', {
url: '/artist',
templateUrl: 'xxxxx',
controller: 'xxxxCtrl'
})
.state('artist.events', {
url: '/events',
templateUrl: '/templates/events/events.html',
controller: 'eventsCtrl'
})
.state('artist.extra-info', {
url: '/extra_info',
templateUrl: '/templates/extra-info.html'
})
.state('artist.articles', {
url: '/articles',
templateUrl: '/templates/articles/articles.html',
controller:'articlesCtrl'
})
});
(or)
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('artist', {
url: '/artist',
templateUrl: 'xxxxx',
controller: 'xxxxCtrl'
})
.state('events', {
url: '/events',
parent:'artist',
templateUrl: '/templates/events/events.html',
controller: 'eventsCtrl'
})
.state('extra-info', {
url: '/extra_info',
parent:'artist',
templateUrl: '/templates/extra-info.html'
})
.state('articles', {
url: '/articles',
parent:'artist',
templateUrl: '/templates/articles/articles.html',
controller:'articlesCtrl'
})
});

AngularUI Router - Nested abstract routes not working

I'm adapting a template called Pages for an AngularJS app and I'm configuring nested view with the UI Router. It seems that everything is in place but the nested route "app/email" doesn't work, whenever it is called UI Router triggers "app/home" as the otherwise statement.
My code is this:
function($stateProvider, $urlRouterProvider, $ocLazyLoadProvider) {
$urlRouterProvider
.otherwise('/app/home');
$stateProvider
.state('app', {
abstract: true,
url: '/app',
templateUrl: "tpl/app.html"
})
.state('app.home', {
url: '/home',
templateUrl: "tpl/home.html",
controller: 'HomeCtrl',
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([
], {
insertBefore: '#lazyload_placeholder'
})
.then(function() {
return $ocLazyLoad.load([
'assets/js/controllers/home.js'
]);
});
}]
}
})
.state('app.email', {
abstract: true,
url: '/email',
templateUrl: 'tpl/apps/email/email.html',
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([
'menuclipper',
'wysihtml5'
], {
insertBefore: '#lazyload_placeholder'
})
.then(function() {
return $ocLazyLoad.load([
'assets/js/apps/email/service.js',
'assets/js/apps/email/email.js'
])
});
}]
}
})
.state('app.email.inbox', {
url: '/inbox/:emailId',
templateUrl: 'tpl/apps/email/email_inbox.html'
})
.state('app.email.compose', {
url: '/compose',
templateUrl: 'tpl/apps/email/email_compose.html'
});
}
An abstract state can have child states but cannot get activated itself. An 'abstract' state is simply a state that can't be transitioned to. It is activated implicitly when one of its descendants are activated.
check this link for more details about abstract in State Provider.
you can use email state as abstract like below code.
.state('app.email', {
abstract: true,
url: '/email',
template : '<ui-view></ui-view>'
})
.state('app.email.default', {
url: '/',
templateUrl: 'tpl/apps/email/email.html',
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([
'menuclipper',
'wysihtml5'
], {
insertBefore: '#lazyload_placeholder'
})
.then(function() {
return $ocLazyLoad.load([
'assets/js/apps/email/service.js',
'assets/js/apps/email/email.js'
])
});
}]
}
})
.state('app.email.inbox', {
url: '/inbox/:emailId',
templateUrl: 'tpl/apps/email/email_inbox.html'
})
.state('app.email.compose', {
url: '/compose',
templateUrl: 'tpl/apps/email/email_compose.html'
});

AngularJS UI-Router default views

Here's the example code.
http://plnkr.co/edit/jXEQ9xemL1A5b9KKKcAw?p=preview
var app = angular.module('npAdmin', ['ui.router']);
app.config(['$httpProvider', '$stateProvider', '$urlRouterProvider',
function($httpProvider, $stateProvider, $urlRouterProvider) {
$stateProvider
.state('common', {
templateUrl: 'tpl.common.html',
abstract: true,
// views: {
// 'footer': {
// templateUrl: 'footer.html'
// }
// }
})
.state('common.dashboard', {
url: '/dashboard',
views: {
'content': {
template: '<div><h4>dashboard</h4></div>'
},
'footer': {
templateUrl: 'footer.html'
}
}
})
.state('common.crm', {
url: '/crm',
views: {
'content': {
template: '<div><h4>CRM</h4></div>'
},
'footer': {
templateUrl: 'footer.html'
}
}
})
.state('common.abc', {
url: '/abc',
views: {
'content': {
template: '<div><h4>ABC</h4></div>'
},
'footer': {
templateUrl: 'newfooter.html'
}
}
})
.state('landing', {
templateUrl: 'tpl.login.html',
abstract: true,
})
.state('landing.login', {
url: '/login',
template: '<div><h4>Wow</h4></div>',
});
$urlRouterProvider.otherwise('/crm');
}
]);
The default 'templateUrl' of 'footer' is 'footer.html', but it's 'newfooter.html' for some state.
Is there a good way to set default footer in this case?
I tried to use 'templateUrl' and 'views' at the same time, but it doesn't work.
There is updated plunker. We can use absolute naming in the parent 'common':
.state('common', {
abstract: true,
views: {
'': {
templateUrl: 'tpl.common.html',
},
'footer#common': {
templateUrl: 'footer.html'
}
}
})
And override it only if needed ('dashboard' and 'crm' will use the parent footer, while the 'abc' is defining an override - special one: newfooter.html)
.state('common.dashboard', {
url: '/dashboard',
views: {
'content': {
template: '<div><h4>dashboard</h4></div>'
},
// provided by parent
//'footer': {
// templateUrl: 'footer.html'
//}
}
})
.state('common.crm', {
url: '/crm',
views: {
'content': {
template: '<div><h4>CRM</h4></div>'
},
// provided by parent
//'footer': {
// templateUrl: 'footer.html'
//}
}
})
.state('common.abc', {
url: '/abc',
views: {
'content': {
template: '<div><h4>ABC</h4></div>'
},
'footer': {
templateUrl: 'newfooter.html'
}
}
Check it here
View Names - Relative vs. Absolute Names
Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.
For example, the previous example could also be written as:
.state('report',{
views: {
'filters#': { },
'tabledata#': { },
'graph#': { }
}
})

Angular UI Router multiple/named routes

I have a user layout file that is the template for any user pages:
<div class="user-wrapper">
<div ui-view="menu"></div>
<div ui-view="content"></div>
</div>
Depending on the state I want the menu to be different. Such as:
.state('user', {
url: '/user',
templateUrl: 'partials/user.html',
controller: 'userController',
})
.state('user.one', {
url: '/one',
controller: 'oneController',
views: {
"menu": { templateUrl: "partials/client-menu.html" },
"content": { templateUrl: "partials/one.html" }
},
});
.state('user.two', {
url: '/two',
controller: 'twoController',
views: {
"menu": { templateUrl: "partials/client-menu.html" },
"content": { templateUrl: "partials/two.html" }
},
});
.state('user.three', {
url: '/three',
controller: 'threeController',
views: {
"menu": { templateUrl: "partials/admin-menu.html" },
"content": { templateUrl: "partials/three.html" }
},
});
Now you can see "one" and "two" both use the same menu but "three" uses a different menu. This all works fine but is there a way to avoid duplicating the menu on "one" and "two".
Such as making a "user.client" state that uses the "user-menu.html" then "one" would be "user.client.one" instead and only have to specify the content.
I think the main problem is the
<div ui-view="content"></div>
is on the grandfather of the "user.client.one" so how can it specify the content?
I would say, that the trick is to move the "menu" view definition into parent state "user"
.state('user', {
url: '/user',
views: {
"" : {
templateUrl: 'partials/user.html',
controller: 'userController',
},
"menu#user": { templateUrl: "partials/client-menu.html" },
},
...
So, what happened? any child state of the "user" will already have the content of the "menu" filled, with the default templateUrl: "partials/client-menu.html"
Any other child, can override that...
.state('user.one', {
url: '/one',
controller: 'oneController',
views: {
// "menu": already set by parent
"content": { templateUrl: "partials/one.html" }
....
.state('user.two', {
url: '/two',
views: {
// "menu": set in parent
"content": { templateUrl: "partials/two.html" }
...
.state('user.three', {
url: '/three',
controller: 'threeController',
views: {
// here we override that
"menu": { templateUrl: "partials/admin-menu.html" },
"content": { templateUrl: "partials/three.html" }
...
Maybe, check this Q & A for some more ideas about multi view nesting:
multiple ui-view html files in ui-router
AngularJS ui-router view structure product site
I think a found a solution user the # for absolute views:
.state('user', {
url: '/user',
templateUrl: 'partials/user.html',
controller: 'userController',
})
.state('user.client', {
url: '/client',
views: {
"menu": { templateUrl: "partials/client-menu.html" }
},
})
.state('user.admin', {
url: '/admin',
views: {
"menu": { templateUrl: "partials/admin-menu.html" }
},
})
.state('user.client.one', {
url: '/one',
controller: 'oneController',
views: {
"content#user": { templateUrl: "partials/one.html" }
},
});
.state('user.client.two', {
url: '/two',
controller: 'twoController',
views: {
"content#user": { templateUrl: "partials/two.html" }
},
});
.state('user.admin.three', {
url: '/three',
controller: 'threeController',
views: {
"content#user": { templateUrl: "partials/three.html" }
},
});
It feels abit cleaner but I'm not sure if its the right approach still.

AngularJS ui-router navigate to url

I'd like to navigate to the following url through the browser:
http://localhost:9001/jira.
This only works if I add a hash to the url, like this:
http://localhost:9001/#/jira.
I tried setting the html5Mode to true, but this only removes the hash from the url. It still does not allow me to navigate directly to the url.
Here is my code:
grey.config( function( $stateProvider, $provide, $locationProvider ) {
$locationProvider.html5Mode( true ).requireBase( false );
// Set up the different views
$stateProvider
.state('index', {
url: '',
views: {
'jira_filters': {
templateUrl: 'app/partials/jira_filters.html'
},
'ciq_filters': {
templateUrl: 'app/partials/ciq_filters.html'
},
'priority': {
templateUrl: 'app/partials/priority.html'
},
'status': {
templateUrl: 'app/partials/status.html'
},
'rca': {
templateUrl: 'app/partials/rca.html'
},
}
})
.state('jira', {
url: '/jira',
views: {
'jira_filters': {
templateUrl: 'app/partials/jira_filters.html'
},
'ciq_filters': {
templateUrl: 'app/partials/ciq_filters.html'
},
'priority': {
templateUrl: 'app/partials/priority.html'
},
'status': {
templateUrl: 'app/partials/status.html'
},
'rca': {
templateUrl: 'app/partials/rca.html'
},
}
});
});

Resources