Angular hashbangs ui-router - home state - angularjs

I'm using ui-router in Angularjs and I have the following routes (as part of my app.js file):
...
$urlRouterProvider.otherwise('/dashboard');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'views/home.html',
data: { public: true }
})
.state('login', {
url: '/login',
templateUrl: 'views/login.html',
data: { login: true }
})
...
I have decided to keep the # in my routes because ui-router doesn't work too well with the html5 setting for routing without the hash.
Question: When I navigate to localhost:8080/ I would expect my home state to kick in but it goes to /dashboard (the otherwise route). I can only access the root of my site with localhost:8080/#/ - is this expected behaviour?

Not the answer for the question, but you might want to take a look at http://angular-route-segment.com for this case, as it works on top of built-in ngRoute module which plays well with html5 mode as well.

Related

angular-ui-router always appends app to url

The ui-router in our angular application always appends "#app" to the URLs in our app, which clearly is not desired behaviour. This also has the side-effect, that when you use the browser navigation (back and forward), you'll need two clicks to actually switch the page.
AngularJS version: 1.2.29
ui-router version: 0.2.10
The browser history looks like so:
http://localhost:8080/app/#/modulename
http://localhost:8080/app/#/modulename#app <- unnecessary step
http://localhost:8080/app/#/anothermodule
http://localhost:8080/app/#/anothermodule#app <-unnecessary step
... and so on.
We already tried switching to ui-router's html5mode, but this just omits the first hash-sign in the URL and doesn't have any effect on anything else.
This is our stateProvider
$stateProvider
.state('app', {
abstract: true,
url: '/',
// parent: true,
templateUrl: CONFIG.baseUrl + '/js/modules/Core/View/app.html',
})
.state('access.404', {
url: '/404',
templateUrl: 'tpl/page_404.html'
});

angular ui-router for dynamic page url

I have an angular app where I am using ui-router module. I am storing a "page" in database with URL and content. I also have some other states/URLs that have their own template. For example:
$stateProvider
.state('landing', {
url: '/',
templateUrl: 'landing-page.html'
})
.state('admin', {
url: '/admin',
templateUrl: 'admin.html'
})
.state('user', {
url: '/user',
templateUrl: 'user.html'
})
I want to define a state for the pages using something like
.state('page',{
url: '??',
templateUrl: 'page.html'
})
What should be in the url above if my page is dynamically stored in database with a URL/slug and content. How can I add the URL/slug here ? If I try this below:
.state('page', {
url: '/{path:.*}',
templateUrl: 'page.html'
})
Then it routes every page including the other states to the same template. I can always prefix the URL with something like /page but I don't want to do that. I want to be able to load the page as :
www.mysite.com/page-1
www.mysite.com/whatever-url
etc
Never mind. I figured this out. The trick was more about using regular expression. Here is my solution
.state('page', {
url: '/{path:(?!admin|user)[a-z0-9\-]+}',
templateUrl: 'page.html'
})
This will ignore routes starting with /admin and /user which we want first. Then, it will check if the url has at least 1 character.

Angularjs Default routes in html5Mode

In my multi languages angular app, I want the default to be English
This is my routes
$urlRouterProvider.otherwise("/en");
//
// Now set up the states
$stateProvider
.state('app', {
abstract: true,
url: '/{lang:(?:he|en)}',
template: '<ui-view/>'
}).state('app.home', {
url: '',
templateUrl: "Assets/app/templates/home.html",
controller: 'homeController'
})
The $urlRouterProvider.otherwise worked as expected, and if i enter to my domain
http://example.com
the URL changed to http://example.com/#/en
My problem is that i change the routes to html5Mode (for seo)
$locationProvider.html5Mode(true);
In the html5Mode when i enter to my domain http://example.com, the URL doesn't change to http://example.com/en as expected.
In short how can i add default routing in html5 mode?
Thanks

ionic routing issue, shows blank page

I started building ionic app on top of the sidemenu starter app. The starter app has a base state 'app' which is abstract and all the sidemenu pages are children of the app for example app.search, app.browse, app.playlists etc.
I have similar hierarchy. However, I want the start page to be some other page, which means it is at the app level.
The states look like this:
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('join', {
url: "/join",
views: {
'menuContent' :{
templateUrl: "templates/join.html",
controller: 'joinCtrl'
}
}
})
.state('app.search', {
url: "/search",
views: {
'menuContent' :{
templateUrl: "templates/search.html",
controller: 'searchCtrl'
}
}
})
.state('app.results', {
url: "/results",
views: {
'menuContent' :{
templateUrl: "templates/results.html",
controller: 'resultsCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/join');
When I run the app, the url defaults to
http://192.168.1.4:8100/#/join
and shows a blank page. Obviously, the join.html is not blank. Also, the console.log messages in joinCtrl are not outputted.
I am not able to figure out why is it not loading the join page. When I change the otherwise to point to '/app/search', everything works.
Any idea what's going on? How do I load the initial page by default and then navigate to the 'app.search' state?
I would expect that because the app is abstract - it is there for a reason. To be parent/layout state. In its template should most likely live all other states.
If yes - check this working example I created to demonstrate that. What we need is to mark the join as a child of the app state. Then the 'menuContent' placeholder will be properly searched in the app template:
.state('join', {
parent: 'app',
url: "^/join",
views: {
'menuContent': {
templateUrl: "tpl.join.html",
controller: 'joinCtrl'
}
}
})
There is a working plunker
The definition url: "^/join", is there to support the idea, that the url defined like this:
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/join');
will work even for nested state (join is child of app). See:
Absolute Routes (^)
If you want to have absolute url matching, then you need to prefix your url string with a special symbol '^'.
This is just one way... we can do the similar stuff if the join is not nested state, but then it should target the unnmaed view '' instead of 'menuContent'

AngularJS - Nested states

When using nested states from UI Router, this will only work if you navigate the page through the nest. i.e.:
If I have
.state('home', {
url: '/',
templateUrl: 'home.html'
...
})
.state('home.page', {
url: '/page',
templateUrl: 'page.html'
...
})
.state('home.page.sub' , {
url: '/page/sub',
templateUrl: 'sub.html'
...
})
Now the problem is if I directly visit /page/sub without going to / and then click on link to go to /page and finally navigate to /page/sub, then the linking is not proper and the elements of the page will not fully load.
How can I fix this linkage issue?
Almost the same issue could be found here:
angular ui-router parent url set to /
I've created plunker showing a working example. The trick here is to use one of the ui-router features:
Absolute Routes (^)
As we can observe in the plunker/code snippet below, we have to adjust the state definition. We need to be able to distinguish among states just by the passed url route
1) first level, a home state, will be used for path '/'
2) second level, a page state, won't be using the parent url, but will be defined as '/page' ... starting from the root.
Therefore ui-router will be able to decide which state to issue. Without the Absolute Routes (^) we would need combine parent and child: '//page' would be the proper route...
.state('home', {
url: '/',
templateUrl: 'home.html'
...
})
// here is the change, see the ^
.state('home.page', {
url: '^/page',
templateUrl: 'page.html'
...
})
.state('home.page.sub' , {
url: '/page/sub',
templateUrl: 'sub.html'
...
})
And now, each state could be accessed as
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="home.page">- Page</a></li>
<li><a ui-sref="home.page.sub">- - Sub</a></li>
And its url will be:
#/ -- this is home
#/page -- the page, in fact starting from root
#/page/sub
Working plunker: plunker

Resources