AngularJS ui-router state won't follow route - javascript

What's wrong with this syntax?
if I click this link: #/app/games/game/{{id}}/team
it redirects to: #/app/games instead of going to the above
gameitem.html template:
<a class="tab-item" ng-href="#/app/games/game/{{id}}/team">Team</a>
which renders to: #/app/games/game/2/team
the routing state:
.state('app.game', {
url: "/games/game/:id",
views: {
'menuContent': {
templateUrl: "templates/gameitem.html",
controller: 'GameItemController'
}
}
})
.state('app.game.team', {
url: "/games/game/:id/team",
views: {
'menuContent': {
templateUrl: "templates/gameitem-team.html",
controller: 'GameItemTeamController'
}
}
})

Don't use ng-href with ui-router. Instead use ui-sref.
ui-sref="app.game.team({id:id})"

Use ui-sref, that way you directly point to your state, so you can afterwards change the URL and it will handle that for you templatewise:
<a class="tab-item" ui-sref="app.game.team({'id': id})">Team</a>
Reference:
https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref
And pointed out by Martin in the comments, the URL property in a childstate, appends the used value to the parent's URL. Prepending it with ^ makes it an absolute route.
Reference:
https://github.com/angular-ui/ui-router/wiki/URL-Routing#url-routing-for-nested-states

You should use ui-sref, as mentioned in previous answers. But couse of your problem is erroneously defined url in sub state.
'app.game' is parent state, 'app.game.team' substate - because dot notation (https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#dot-notation).
In nested states are url concatenated. Correct url of 'app.game.team' state should be "/team" only (see https://github.com/angular-ui/ui-router/wiki/URL-Routing#url-routing-for-nested-states)

Related

Otherwise for states with typed parameters

I started using typed parameters (such as {id:int}) in my route configuration. If a state doesn't match because of the type, otherwise does not appear to trigger.
For example:
$stateProvider
.state('stuff', {
url: '/version/{version:int}/stuff',
templateUrl: // ...,
controller: // ...
})
.state('list', {
url: '/list',
// ...
});
$urlRouterProvider.otherwise('/list');
If the version is "x" (not an int), I am not redirected to the list page. Instead I end up on an empty page with no errors in the console.
How can I fix this?
(Clarification: I'm typing in invalid URLs in the address bar to test this, not using ui-sref.)
Update: I believe I've found what's causing it (thanks to #RadimKöhler for an example that eliminated some possibilities). See my plunk.
Everything works fine except for URLs that fail to match a custom type built with $urlMatcherFactoryProvider.type(). I used a guid type based on the answers to this question.
I can work around this by using regular expressions in the URL, but it would be nice to have a fix.
More info: Adding pattern to the custom Type object appears to fix this. The pattern has to leave out the anchors (^$), so something like:
pattern: /[a-f\d]{8}-(?:[a-f\d]{4}-){3}[a-f\d]{12}/i
I'd say, that the concept as you wanted, is working. There is a working example
this state def (1:1 to question)
$stateProvider
.state('stuff', {
url: '/version/{version:int}/stuff',
templateUrl: 'tpl.html',
controller: 'StuffCtrl',
})
.state('list', {
url: '/list',
templateUrl: 'tpl.html',
controller: 'ListCtrl',
});
$urlRouterProvider.otherwise('/list');
will properly handle these links:
// list
<a href="#/list">
// ui-sref
<a ui-sref="stuff({version:1})">
<a ui-sref="stuff({version:2})">
// href
<a href="#/version/12/stuff">
these will not work (as expected) - so they will not created any href (such state with such params does not exist)
<a ui-sref="stuff({version:'A'})">
<a ui-sref="stuff({version:'xyz'})">
these href will be redirect to otherwise
<a href="#/version/x/stuff">
<a href="#/version/AB/stuff">
Check it in action here

angularJs stateprovider sub state doesn't load controller and template

I created this small app where I have following states:
restricted.route.js
$stateProvider.state('restricted', {
url: '/restricted',
templateUrl: 'app/restricted/restricted.html',
abstract: true
});
pages.route.js
$stateProvider.state('restricted.pages', {
url: '/pages',
templateUrl: 'app/restricted/pages/pages.html',
controller: 'pagesController',
controllerAs: 'vmPages'
});
detail.route.js
$stateProvider.state('restricted.pages.detail', {
url: '/:id',
controller: 'pageDetailController',
controllerAs: 'vmDetail',
templateUrl: 'app/restricted/pages/detail/detail.html'
});
app.run.js
$urlRouterProvider.otherwise('/restricted/dashboard');
When I load the URL #/restricted/pages everything works fine. Controller is loaded and view is shown.
When I load the URL #/restricted/pages/1 the controller and view from the state 'restricted.pages' is loaded and executed.
The state is clearly recognized, because the $urlRouterProvider.otherwise is not executed.
Does anyone have an idea what I'm doing wrong here?
Thanks!
Is it intentional to have the details as a substate of the pages (list?) state? If so, you need to place an <div ui-view></div> into the template named app/restricted/pages/pages.html.
If that was not your intention, I recommend to rename the detail state to something like restricted.pages_detail as every dot introduces a nested level in the state definitions.
I think your issue lies in the HTML, the nested state should be loaded in a ui-view tag on the parent element.

Angular UI-Router - parameters in child and parent state returning wrong template

I have an application based on Angular with the UI-Router. I'm trying to get the following URL structure
/base/category
/base/category/id
while serving different templates for each route.
I've been searching around a lot but couldn't find anything that helps me.
My code:
$stateProvider
.state('app', {
url: '',
templateUrl: 'views/app.html',
abstract: true
})
.state('base', {
url: '/base',
template: '<div ui-view></div>',
abstract: true,
parent: 'app'
})
.state('base.cat', {
url: '/:catId',
templateUrl: 'views/cat_view.html'
})
.state('base.cat.id', {
url: '/:id',
templateUrl: 'views/id_view.html'
});
Accessing /base/category returns the correct template, but /base/category/id also returns the category template (I want it to return id_view.html). I might want to add more dynamic parameters later on so I want a clean solution for this.
This is my workaround for now:
.state('base.id', {
url: '/:catId/:id',
templateUrl: 'views/id_view.html'
});
It works but the UI-Router doesn't trigger the active classes in my menu.
Thanks for taking time to read this, if you just point me in the right direction that helps me a lot!
There is a working example with the code above
Your concept is ok, just be sure, that parent has place for its child:
<div ui-view></div>
So, in our case, I added the above line into views/cat_view.html. That is the parent state view of the state 'base.cat.id'. These links are now working:
<a href="#/base/category">
<a href="#/base/category/1">
<a href="#/base/category/22">
Check it in action here

AngularJS simple navigating to parameterized state via URL ui-router

I am trying to enter a ui-router parent or child state simply by navigating to its associated URL. I know that ui-sref is a proven, simple way to enter into a state via an a link, but just typing the URL of a state into a browser seems to always redirect me to my $urlRouterProvider.otherwise() statement.
For example, I would like to be able to navigate into the page state, via going to example.com/#/page in the browser. Instead, I am redirected to the otherwise.
JS
angular.module('app', [ 'ui.router', 'subapp']);
angular.module('app').config(function($urlRouterProvider, $locationProvider) {
}).controller('appCtrl', function(){});
angular.module('subapp', ['ui.router']);
angular.module('subapp').config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when('#/page/nothing', '/');
$stateProvider
.state('page', {
url: '#/page',
templateUrl: 'page.tpl.html'
})
.state('page.edit', {
url: '/:myparameter',
templateUrl: 'page-edit.tpl.html'
});
$urlRouterProvider.otherwise('/hello');
});
Index.html
<body ng-controller="appCtrl">
This is the index.html file<br>
Go to page state<br>
Go to page child state with a parameter
<ui-view></ui-view>
PLNKR: http://plnkr.co/edit/HQziTB2CyJrCvbgzzuJm?p=preview
ote I have a subapp service which is injected into the main app—but I don't think that would make a difference, as page state should still be a 'top-level' state injected into the index.html <ui-view>
How can I make it so that I can navigate to a URL (even one with a parameter) directly? The documentation says its possible, but I can't seem to get it to work.
I would say, that you are almost there. There is an updated plunker. But while your links could (should) be with # (we are not using html5Mode)
<a href="#/page">
<a href="#/page/myparameter">
<a href="#/page/11">
The state definition should not contain that sign:
.state('page', {
// instead of this
// url: '#/page',
// we need this
url: '/page',
...
.state('page.edit', {
// instead of this
// url: '#/:page',
// we need this
url: '/:page',
And then also these will work:
<a ui-sref="page">
<a ui-sref="page.edit({page:123})">
<a ui-sref="page.edit({page:444})">
Check it here
Your parameter URL is wrong, you cannot map URL with a fixed name and other url with a parameter cause will cause a crazy rewrite thinking this is a variable
$stateProvider
.state('page', {
url: '#/page',
templateUrl: 'page.tpl.html'
}
).state('page.edit', {
url: '/:myparameter',
templateUrl: 'page-edit.tpl.html'
});
Use URL by this way:
$stateProvider
.state('page', {
url: '/page',
templateUrl: 'page.tpl.html'
}
).state('page.edit', {
url: '/page/:myparameter',
templateUrl: 'page-edit.tpl.html'
});

Can't navigate to ui-router state with URL

I'm working on a simple angular application using ui-router. I have a couple states for selecting and then editing information about a publisher. The relevant config:
.state('select-publisher', {
url: '/select-publisher',
templateUrl: '/Content/superadmin/src/templates/publishers/publishers.html'
})
.state('publisher', {
abstract: true,
url: 'publisher/{id:int}',
templateUrl: '/Content/superadmin/src/templates/publishers/publisher.html'
})
.state('publisher.details', {
url: '/details',
templateUrl: '/Content/superadmin/src/templates/publishers/details.html'
})
.state('publisher.ad-tags', {
url: '/ad-tags',
templateUrl: '/Content/superadmin/src/templates/publishers/ad-tags.html'
})
.state('publisher.native-ads', {
url: '/native-ads',
templateUrl: '/Content/superadmin/src/templates/publishers/native-ads.html'
})
Inside the select-publisher state I have a big list of available publishers. Each one of them is bound to an ng-click event that triggers the following function in my controller:
$scope.selectPublisher = function(publisher) {
publisherService.setSelectedPublisher(publisher);
$state.go('publisher.details', {id: publisher.Id});
};
This works just fine and takes me to the publisher.details state and renders the proper view. At this point the URL in my browser points to localhost:1337/superadmin#/publisher/39/details where 39 is the ID of the publisher that I selected.
The problem is, if I refresh this page or attempt to navigate directly to it by pasting the URL into the browser from another area of the application, I am ALWAYS taken back to the select-publisher state. I would like to be able to configure my states such that I am able to navigate to the details state (or any other state) based on URL.
Worth noting is that I do have a catch all route defined after all of my states:
$urlRouterProvider.otherwise('/select-publisher');
I'm assuming that for some reason this is being triggered but I can't reason as to why navigation works in my app using either $state.go as I have indicated in my controller as well as using ui-sref directive in my HTML templates but not through navigating directly to the URL.
Maybe it's because of missing slash url: /publisher/{id:int}

Categories

Resources