How to switch to a ui-router state conditionally? - angularjs

I am writing a CRUD app with AngularJS + UI Router.
I want to be able to parse the current location in the browser URL and determine if a ui-router state should be applicable for the current url.
In these sample routes, is there some way to do the if and unless clauses?
(url in browser address bar is http://example.com/notes/1/edit_me)
$stateProvider.state("root", {
url: "",
unless: $location.matches(/\edit_me/)
})
$stateProvider.state("edit", {
url: "/edit",
if: $location.matches(/\edit_me/)
//
})
UPDATE 1
The reason I want to do the above:
Say I am at http://example.com/notes. The routes is
$stateProvider.state("root", {
url: "",
})
However, with the same above ui.route state, when I am at url http://example.com/notes/edit, the root is now "/notes/edit" instead of "/notes"
UPDATE 2
#adam, more explanation of what I am trying to accomplish:
I will try to explain: in your code, for your home state, the (ui.router's) url is / (aka hash syntax #!/)
However, the URL in browser address bar looks like http://example.com/notes/ in one case and http://example.com/notes/edit in another case. (note that the URLs do not contain any #! portion since we have just navigated to the page)
Now the home's / is going to match in both cases of above URL.
But since the second URL ends in notes/edit, I want that the home for this URL should be #!/edit, and not #!/.
Basically I am trying to mix server-side rendered pages (/notes and /notes/edit are rendered by server, not AngularJS)
and client side routing so that no matter which URL we are at, the client can figure out which (ui.router) route applies to the current URL.
Make sense?

Sorry i don't really understand your needs but here's an example of use of ui-router:
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/main/index.html',
controller: 'MainCtrl'
})
$stateProvider
.state('edit', {
url: '/edit',
templateUrl: 'app/edit/edit.html',
controller: 'EditCtrl'
})
$stateProvider
.state('edit.note', {
url: '/note',
templateUrl: 'app/edit/note.html',
controller: 'NoteCtrl'
});
$urlRouterProvider.otherwise('/');
i'm not sure if a copy paste will work, but try to adapt it with your case. Hope it will help.
Edit:
I'm afraid that i can't help you more than that. The design of your app with rendered page without angular sounds really special.
Have you tried the example i provide you? If yes, hav you simply format the url by addind
" #!/ " where you need it.
For example:
$stateProvider
.state('edit', {
url: '#!/edit', //or something like, url:'/#!/edit'
templateUrl: 'app/edit/edit.html',
controller: 'EditCtrl'
});
Check this link also may be it will help you:https://github.com/angular-ui/ui-router/issues/372
ui-sref may help you
But the place to see usefull example for ui-router it's his own doc.
https://github.com/angular-ui/ui-router
and here:
http://angular-ui.github.io/ui-router/site/#/api/ui.router

Related

passing parameters in nested views with ui-router

I am running into trouble understanding how you can correctly pass parameters using AngularJS.
This is the code I was trying to use in my app.js file for the nested views, however, the nest state never properly renders.
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('news', {
url: '/news',
templateUrl: 'templates/news.html',
controller: 'NewsCtrl'
})
.state('news.id', {
url: '/news/:id',
templateUrl: 'templates/news.id.html',
controller: 'NewsCtrl'
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/news');
})
It will try and change the url to #/news/news/:id versus just #/news/:id.
And if I try and change the path to just be the #/news/:id, then the pages do not render correctly.
What is the best approach to achieve these nested views with parameters?
According to ui-route wiki:
When using url routing together with nested states the default
behavior is for child states to append their url to the urls of each
of its parent states.
If you want to have absolute url matching, then you need to prefix
your url string with a special symbol '^'.
So in your case, you should try
.state('news.id', {
url: '^/news/:id',
templateUrl: 'templates/news.id.html',
controller: 'NewsCtrl'
});

$urlRouterProvider.otherwise not going to default route

I am stuck with this for a while. I am very much new to ui-router's nesting of views. I am trying to route to default when "/" accessed. Here's my js file:
angular
.module("app")
.config(function($stateProvider,$locationProvider,$urlRouterProvider){
$urlRouterProvider.otherwise("dashboard");
$stateProvider
.state("home",{
url: "/",
templateUrl: "views/home/home.html"
})
.state("login",{
url: "/login",
templateUrl: "views/login/login.html"
})
.state("home.dashboard",{
url: "/dashboard",
templateUrl: "views/home/dashboard.html"
});
$locationProvider.html5Mode(true);
});
I don't know why that's not working. Every time I try to load localhost, it's not going to localhost/dashboard. Rather, it stops loading till home.html. Please help me in learning something new and showing my mistake.
Please see this working plunker. I turned off the HTML5 mode because it prevents plunker to work correctly.
The main problem with your code was that you were redirecting to /dashboard, in this statement:
$urlRouterProvider.otherwise("/dashboard");
Please note that home.dashboard is a child state of home. So, by default, the URL should be preceded by that of the home state. So the correct statement would be:
$urlRouterProvider.otherwise("/home/dashboard");
If you don't want the preceding /home, you need the change your route configuration for home.dashboard state to this:
.state("home.dashboard", {
url: "^/dashboard",
templateUrl: "dashboard.html"
});
The preceding ^ makes the URL absolute and makes it free of any preceding parent state's URL. So now, the statement $urlRouterProvider.otherwise("/dashboard"); will work as is.
After this change, the code could load the template home.html in the view. Further, you didn't have any ui-view directives in home.html in which the template of home.dashboard could load. So I added a <div ui-view></div> element in home.html to make it work correctly.

Avoiding dynamic routes with ui-router

I am using express, angular, and ui-router for my webpage. I would like the url for each user's page to be very simple: www.mysite.com/username
This is similar to Twitter's design. My angular state provider for the user pages looks like this:
$stateProvider
.state('userPage', {
url: '/:username',
templateUrl: 'js/user-page/user-page.html',
controller: 'UserPageCtrl'
});
The only issue is now when I try to navigate to any other page whose state is defined with only one URL part (ie. www.mysite.com/login), the app always parses the URL as a user page (but without being able to find a user).
Is there any way to tell angular to try and load the URL as a defined state before treating the url as a dynamic parameter?
I can simply require all other routes to have two parameters (ie. www.mysite.com/login/userlogin), but that doesn't seem very elegant.
You just need to define the login state first. Order is important.
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'somewhere/login.html',
controller: 'LoginPageCtrl'
},
.state('userPage', {
url: '/:username',
templateUrl: 'js/user-page/user-page.html',
controller: 'UserPageCtrl'
},
});
If a user navigates to /login then a matching state will be searched for. It will check your first state, then the second and so on until a matching state is found. In this case, the login state will match so the searching for another matching state will cease.

ui-route how to render multi ui-view when route to template

my requirement is:
index.html
-- /login
-- /main/tab1
-- /main/tab2
-- /userinfo
And the ui will be like:
header: logo, userinfo
left-nav: switch tab1/tab2/tabN
right content: ui-view to change, and multi sub ui-view,
And UI detail:
login will be a independent page, no header, left-nav, right content
main/tab will only change the right content
/userinfo will replace the left-nav and right content to some userinfo page, remain the header, of course using ui-view
I've seen the ui-route demo, but follow the demo, I don't know how to build the route config to what I want, so could any one help me ? The ui-route config is a little complex.....
If my url define is not perfect, please help me improve the url structure, thanks
If you have seen the demo and understood it, this should make sense:
.state('index', {
url: '/',
templateUrl: //your index.html template path,
controller: // your controller if any for index page
})
.state('index.login', {
url: '/login',
templateUrl: // your login template,
controller: // controller for login page
})
.state('index.mainTab1', {
url: '/main/tab1',
templateUrl: // your tab1 template,
})
add the other states in the same manner and you should be ready to go.

AngularJS multiple routes using JSON data ids

We are new to AngularJS and finding one-or-two problems with setting up multiple routes when using ID's from Json Data.
We are trying to replicate AngularJS Tutorial, so we can click each 'View' button to display a more detailed page of the selected 'Warranty Item' same as the tutorial.
We have uploaded our AngularJS problem to Plunker, If anyone can see something we're missing or know a better route to go down please let us know.
App.js State with ResultSet.JobID
.state('home.singleWarranty', {
url: '/singlewarranty/{resultset.JobID}',
templateUrl: 'singlewarranty.html',
controller: 'warrantyListController'
})
There is a working/updated plunker
Because there are these states
.state('home', {
url: '/home',
templateUrl: 'home.html',
controller: 'homeController'
})
.state('home.singleWarranty', {
url: '/singleWarranty/:jobID',
templateUrl: 'singlewarranty.html',
controller: 'warrantyListController'
})
We need to build the url like this
View
Instead of this original
// View
The point is that state 'home.singleWarranty' inherits/extends the url from its parent. So we have to include the parents '/home' as well.
Other solution:
In case we would like to start the url in a child state from the begining, we can do it like this
.state('home.singleWarranty', {
url: '^/singleWarranty/:jobID',
See the ^ at the url begining. Then even this would work:
View
Check the updated plunker here

Resources