AngularJS UI-Router "otherwise" state not loading - javascript

My index.html page has 3 views:
<header ui-view="header"></header>
<main ui-view="content"></main>
<footer ui-view="footer"></footer>
I just changed the site to use these 3 views instead of the initial single view.
All the routes in my app work fine, for example the "home" view:
$stateProvider.state('home', {
url: '/home',
data: {
pageTitle: 'Home',
access: 'private',
bodyClass: 'home'
},
views: {
'header': {
templateUrl: 'modules/header/header.html'
},
'content': {
controller: 'HomeController as home',
templateUrl: 'modules/home/templates/home.html'
},
'footer': {
templateUrl: 'modules/footer/footer.html'
}
}
});
My issue is the "otherwise" state in the app does not correctly load the "home" state as it should. The page is blank, no console errors. Here's the state in my app.module:
angular.module('app').config(function ($stateProvider) {
$stateProvider.state('otherwise', {
url: '*path',
template: '',
data: {
pageTitle: '',
access: 'public',
bodyClass: ''
},
controller: function ($state) {
$state.go('home');
}
});
});
What am I missing here?

I am not sure if your wild char works or not.
Ideally I use the following for default routing:
$urlRouterProvider.otherwise('/app/home');

Related

How to navigate from a login state to an abstract dashboard state?

https://plnkr.co/edit/ByatrCzdUJfAV3oc8XPq?p=preview
^ On line 10, if you put back in the abstract:true key you will see the tags view appear in this plnkr app.
However my problem is that in my real app it won't let me use the abstract key because you first start at a login state and then transition to the dashboard state.
And the abstract key allows me to add the additional tags state as a child of dashboard.
When I have that key in there and I login in my real app this is the error I get:
Error: Cannot transition to abstract state 'dashboard'
Plnkr code:
var dash = {
name: 'dash',
url: '/dash?ticker',
// abstract: true,
views: {
'': { templateUrl: 'dashboard.html' },
'tickersList#dash': {
templateUrl: 'tickers-list.html',
controller: 'tickersController'
},
'alertsList#dash': {
templateUrl: 'alerts-list.html',
controller: 'alertsController'
}
}
};
var tags = {
name: 'dash.tags',
url: '?ticker',
params: {
ticker: 'AAA'
},
views: {
'tagsList#dash': {
templateUrl: 'tags-list.html',
controller: 'tagsController'
}
}
}
$stateProvider
.state(dash)
.state(tags);
Real app
LoginController:
$state.go('dashboard')
STATE_CONSTANTS:
dashboard state object:
.constant('STATE_CONSTANTS', {
dash: {
name: 'dashboard',
// abstract: true,
url: `/dashboard?ticker?start_epoch?end_epoch?timespan?group?sort?term_id_1?term_id_2?term_id_3?social?stream?links?retweets?tags_open?feed_open?chart_alerts?chart_max`,
views: {
'': {
templateUrl: 'dash/dashboard_container.html',
controller: function(UserFactory, container, user) {
this.container = container;
UserFactory.storeUser(user);
},
controllerAs: 'dc',
bindToController: true,
resolve: {
user: (AuthFactory) => AuthFactory.check_login(),
settings: (user, UserFactory) => UserFactory.settings(user),
container: ($stateParams, TagsFactory) => TagsFactory.createTerms($stateParams)
}
},
'platformHeader#dashboard': {
templateUrl: 'headers/platform/platform_header.html',
controller: 'PlatformCtrl',
controllerAs: 'ph'
},
'timespanHeader#dashboard': {
templateUrl: 'headers/timespan/timespan_header.html',
controller: 'TimeHeaderCtrl',
controllerAs: 'thc'
},
'tickersPanel#dashboard': {
templateUrl: 'tickers/panel/tickers_panel.html',
controller: 'TickersPanelCtrl',
controllerAs: 'tikp'
},
},
params: {
ticker: '',
},
data: { authorizedRoles: ['All'] }
},
login state object:
login: {
name: 'login',
url: '/login',
templateUrl: 'auth/login.html',
controller: 'LoginCtrl',
data: { authorizedRoles: ['All'] }
}
dashboard.html template
<div>
<header>
<div ui-view="platformHeader"></div>
<div ui-view="timespanHeader"></div>
</header>
<aside>
<!-- the headers and tickersPanel are all child states of
dashboard state -->
<div ui-view="tickersPanel"></div>
<!-- tags is a seperate state from dashboard -->
<div ui-view="tagsPanel"></div>
</aside>
//...
app.js
$stateProvider
.state(STATE_CONSTANTS.login)
.state(STATE_CONSTANTS.password)
.state(STATE_CONSTANTS.passwordreset)
.state(STATE_CONSTANTS.settings)
.state(STATE_CONSTANTS.settingsDefault)
.state(STATE_CONSTANTS.settingsAlerts)
.state(STATE_CONSTANTS.dash)
The behavior is right. You cannot transit to abstract state. Look at your example from plunker.
var dash = {
name: 'dash',
url: '/dash?ticker'
var tags = {
name: 'dash.tags',
url: '?ticker',
You have an abstract state "dash" and you have a child state "dash.tags" which is not abstract. So you can transit only to child state.
In your app, you try transiting to an abstract state which is not possible.
Abstract states are used if you want to have some basic state with common behavior (parent state). You cannot transit to such states but they can have some basic template, resolve functions... So, you have to remove abstract flag or create a child state.

Sub view for $state not rendering in named ui-view

https://plnkr.co/edit/VV13ty8XaQ20tdqibmFy?p=preview
Expected
After login the dashboard state renders dashboard.html, and all components and ui-views should render: tickers, tags, social(named ui-view) and feed.
Results
After login the dashboard state renders dashboard.html however only the components tickers,tags and feed show up, but not the social (named-ui-view)
I feel that my problem lies somewhere around where I transition from the login state to the dashboard state. Once you hit the dashboard state, it serves up the default template which is the component element tag: <dash-module></dash-module>. This will then render the dash.component template: dashboard.html and controller. However I've lost access to the social view in the dashboard state object.
dashboard.html
<div class="jumbotron text-center">
<h1>The Dashboard</h1>
</div>
<div class="row">
<tickers-module></tickers-module>
<tags-module></tags-module>
// Expecting the social-module-template.html to show below:
<div ui-view="social"></div>
<feed-module></feed-module>
</div>
The routerApp module with the dashboard component full code in Plnkr
// RouterApp module
////////////////////////////////////////////////////////////////////////////////
var routerApp = angular.module('routerApp', ['ui.router', 'tickers', 'tags', 'feed']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
const login = {
name: 'login',
url: '/login',
templateUrl: 'login.html',
bindToController: true,
controllerAs: 'l',
controller: function($state) {
this.login = function() {
$state.go('dashboard', {});
}
}
}
const dashboard = {
name: 'dashboard',
url: '/dashboard',
params: {
ticker: {},
tags: {}
},
template: '<dash-module></dash-module>',
views: {
'' : {
templateUrl: 'dashboard.html',
},
'social' : {
templateUrl: 'social-module-template.html',
controller: function($state) {
console.log('Social init', $state.params);
}
}
}
}
$stateProvider
.state(login)
.state(dashboard);
})
tags.component('dashModule', {
templateUrl: 'dashboard.html',
controller: function($scope, $state) {
console.log('dashModule loaded!');
}
})
This is the part that should render the social html content in the <div ui-view="social"></div>
views: {
'' : {
templateUrl: 'dashboard.html',
},
'social' : {
templateUrl: 'social-module-template.html',
controller: function($state) {
console.log('Social init', $state.params);
}
}
}
I made changes to your plunker here You were missing # here.
const dashboard = {
name: 'dashboard',
url: '/dashboard',
params: {
ticker: {},
tags: {}
},
template: '<dash-module></dash-module>',
views: {
'' : {
templateUrl: 'dashboard.html',
},
'social#dashboard' : {
templateUrl: 'social-module-template.html',
controller: function($state) {
console.log('Social init', $state.params);
}
}
}
}
In order for these components to appear under the home state, we must define them using absolute naming. Specifically, we must use the # syntax to tell AngularJS that these components of our application should be mapped to a specific state. This follows the viewName#stateName syntax and tells our application to utilize named views from an absolute, or specific state. You can read more about relative vs. absolute names here.
See this for more information.
The problem you have is named view has to render in same state i.e Dashboard.
Change the following and it should work.
social#dashboard
Check this Plunkr
Named Views UI router

Angular-Ui-Router state changes but template URL doesn't load for nested states

I am working on an a requirejs + angularjs project with ui-router . I tried to implement nested views but only the state changes but the template URL doesn't load.
My route-config.js
.state(ROUTE.auditGroup, {
abstract: true,
authenticate: true,
data: {
pageTitle: 'AuditMain'
},
views: {
'user': {
templateUrl: GLOBAL.viewPath + '/auditgroup.html',
}
}
})
.state(ROUTE.audit, {
url: '/audit',
authenticate: true,
data: {
pageTitle: 'Audit'
},
views: {
'nested': {
templateUrl: GLOBAL.viewPath + '/audit.html',
controller: 'auditCtrl',
}
},
ncyBreadcrumb: {
label: 'Audit',
}
})
.state(ROUTE.allidentifiers, {
url: '/allidentifiers',
authenticate: true,
data: {
pageTitle: 'All Identifiers'
},
views: {
'nested': {
templateUrl: GLOBAL.viewPath + '/audit.allidentifiers.html',
controller: 'allidentifiersCtrl',
}
},
ncyBreadcrumb: {
label: 'All Identifiers',
}
})
My auditgroup.html
<div ui-view="nested"></div>
The Audit Page Works fine but, the allidentifiers page is not injected.
Everything works fine except nested views, I could not figure out the exact problem , state changes successfully but the template URL doesn't load.
Need assistance.
Plunkr https://embed.plnkr.co/oRMnMW4QoWwhSkm9maHf/
Goto > list>Second Nested
I want to include second nested template in same view
You need to have ui-view for the nested template to show. See the updated plunker here: https://plnkr.co/edit/oRMnMW4QoWwhSkm9maHf?p=preview

Angular ui-router not extending parent view

I am trying to extend a parent view to a child view.
My route.js
let view = {
'': {
templateUrl: '/app/content.html'
},
'sidebar': {
templateUrl: '/app/sidebar.html'
}
};
.state('profile', {
abstract: true,
url: '/profile',
views: view,
templateUrl: '/app/profile/profile.html'
})
.state('profile.about', {
parent: 'profile',
url: '/about',
views: {
'': {
templateUrl: '/app/profile/about.html'
}
}
})
My index.html:
<div ui-view></div>
My profile/profile.html:
//all other stuff (header, sidebar, etc)
<div>
<h1>Profile</h1>
<div ui-view=""></div>
</div>
My profile/about.html:
<div>
<h1>About</h1>
</div>
Everything works perfectly including the sidebar.
The problem is that about.html is showing the page but it is not extending the profile/profile.html page.
Any solutions?
Here is the plunker.
It's a little bit different but it is the same, considering how the route1 is not shown but the test.html is show.
Try this way:
let view = {
'': {
templateUrl: '/app/profile/index.html'
},
'content': {
templateUrl: '/app/content.html'
},
'sidebar': {
templateUrl: '/app/sidebar.html'
}
};
.state('profile', {
abstract: true,
url: '/profile',
views: view
})
.state('profile.about', {
parent: 'profile',
url: '/about',
views: {
'': {
templateUrl: '/app/profile/about.html'
}
}
})

Angular UI-Router doesn't match a defined state

I'm using UI-Router module for routing. I have 2 states that router should match the urls with them :
// Dashboard
.state('dashboard', {
url: "/dashboard",
templateUrl: "dashboard/views/index.html",
controller: "DashboardController",
...
})
// Users
.state('users', {
url: "/users",
templateUrl: "users/views/index.html",
controller: "UsersController",
...
})
// Single User
.state('users.id', {
url: "/{id:^[a-z0-9_-]{3,16}$}",
templateUrl: "users/views/show.html",
controller: "UserController",
...
})
also I have set a default route :
$urlRouterProvider.otherwise("/dashboard");
I want the router to match users state when I go to http://127.0.0.1:8000/app/#/users
and to match user state when I go to http://127.0.0.1:8000/app/#/users/testuser
Problem :
the users state works good, but the user state url doesn't get matched and redirects to the default state. What's the problem?
There is a working example
Try to use this regex def:
.state('users.id', {
url: "/{id:(?:[a-z0-9_-]{3,16})}",
These links will work
<a href="#/users">
<a href="#/users/testuser">
This will go to otherwise
<a href="#/users/xx">
Some inspiration could be found here
In case, we want to go to state 'users.id' directly, we just have to use proper call. In this extended plunker, we can see that it could be done like this:
// working
<a ui-sref="users">
<a ui-sref="users.id({id:'testword'})">
// not working - id does not fit - otherwise is used
<a ui-sref="users.id({id:'not-working simply too long'})">
The same would be with $state.go('users.id', {id:'testword'})
Check it here
Here is an example of how I've done it in the past. Maybe it will help you.
app.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider,$rootScope,$cookieStore) {
$urlRouterProvider.otherwise("/login");
$stateProvider
.state('login', {
url: '/login',
title: 'Login',
templateUrl:'views/loginView.html',
controller: 'loginCtrl',
resolve: resolver($rootScope),
})
.state('account', {
url: '/account',
title: 'My Account',
accessLevel: 2,
resolve: resolver($rootScope,$cookieStore),
views: {
'navigation': {
templateUrl: 'views/navigationView.html',
controller: 'navigationCtrl'
},
'content': {
templateUrl: 'views/contentView.html',
controller: 'navigationCtrl'
}
}
})
.state('account.dashboard', {
url:'/dashboard',
title: 'Dashboard',
views : {
'pageContent': {
templateUrl:'views/dashboardView.html',
controller: 'dashboardCtrl'
}
}
})
.state('account.foo', {
url:'/foo',
title: 'foo',
views : {
'pageContent': {
templateUrl:'views/foo.html',
controller: 'fooCtrl'
}
}
})
.state('account.maps', {
url:'/maps',
title: 'Maps and stuff',
views : {
'pageContent': {
templateUrl:'views/mapsView.html',
controller: 'mapsCtrl'
}
}
})
}])

Categories

Resources