Angular ui-router goes to default state on browser refresh - angularjs

Here is my ui-router configuration:
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url : '/',
views : {
'' : {
templateUrl : 'partials/default.ejs',
controller : 'DefaultCtrl'
},
'defaultView#home' : {
templateUrl : 'partials/table.ejs',
controller : 'TenderAppCtrl'
},
'detailView#home' : {
templateUrl : 'templates/viewtender.ejs',
controller : 'TenderDetailCtrl'
}
}
})
.state('about', {
url : '/about',
templateUrl : 'partials/about.ejs',
controller : 'AboutCtrl'
})
.state('settings', {
url : '/settings',
templateUrl : 'partials/settings.ejs',
controller : 'SettingsCtrl'
})
//dummy state used for browser back button functionality only
.state('home.detail', {
url : ':id'
});
No matter where I refresh my browser, the page goes back to '/' state. For eg. if my current state is '/settings' and if I hit browser refresh, I expect the page to reload the state 'settings' but it jumps back to '/'. It seems like $urlRouterProvider.otherwise('/') is triggered eveytime I refresh the page. I tried setting HTMLmode to false but that didn't work either.

Related

Angular ui-router $stateProvider.state's url attribute

I was testing ui-router for my application and wanted to have a default state for my route.
For example, when I go to localhost:3000/r, I can load either /a or /b in the page given as,
app.config(function($stateProvider) {
$stateProvider.state('a', {
templateUrl : '/a',
url : '',
controller : 'mainController'
})
.state('b', {
templateUrl : '/b',
url : '',
controller : 'mainController'
});
});
What exactly is the significance or the url attribute? If i leave it blank it acts as a default state for my route localhost:3000/r and loads /a into the page?
You need to inject another provider to your config function, that will be used to set the default route
And you need to set urls for your current states (a,b)
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/a");
$stateProvider.state('a', {
templateUrl : '/a',
url : '/a',
controller : 'mainController'
})
.state('b', {
templateUrl : '/b',
url : '/b',
controller : 'mainController'
});
});
By doing this, your default route will be "/a"

Angular ui router - fixed menu with dynamic content

I have to create a page with a fixed top menu containing some input and buttons.
Depending on which data is filled in and which button is pressed, a map with data should appears below the menu.
The menu will always be there and only the map will be updated.
ROUTE
$stateProvider
.state('login', {
url : '/login',
templateUrl : 'app/login/login.html',
controller : 'LoginController'
})
.state('home', {
url : '/home',
templateUrl : 'app/home/home.html'
})
.state('menu', {
url : '',
templateUrl : 'app/menu/menu.html',
parent : 'home'
});
home.html
<div ui-view="menu"></div>
<h1 class="ui huge header">
Please select something
</h1>
For the moment I can only see the "Please select something" but not the menu.
After that, how can I replace "Please select something" by the needed map ? Is it possible to have a default view ? When landing on home I should see the message and not a map
EDIT
Here is what I got after the answers
ROUTE
$stateProvider
.state('login', {
url : '/login',
views : {
'login' : {
templateUrl : 'app/login/login.html',
controller : 'LoginController'
}
}
})
.state('home', {
url : '/home',
views : {
'menu' : {
templateUrl : 'app/menu/menu.html'
},
'content' : {
templateUrl : 'app/home/home.html',
}
}
})
.state('home.other', {
url : '/other',
views : {
'content#' : {
templateUrl : 'app/home/home.html'
}
}
});
INDEX.HTML
<div ui-view="login"></div>
<div ui-view="menu"></div>
<div ui-view="content"></div>
It is working well but it is the best way to do it ? I have a lot of different content so I will have to duplicate the menu view inside every state ?
If I have a page with a different layout (without menu and content) - Should I just add a new <div ui-view="list"></div> in index.html ?
EDITED according to question update
Try to read Nested views this article to better understand existing solution in ui-router.
Here is example what you can do to avoid duplication of routes:
$stateProvider
.state('login', {
url: '/login',
views: {
'login': {
templateUrl: 'app/login/login.html',
controller: 'LoginController'
}
}
})
.state('menu', {
url: '/menu',
templateUrl: 'app/menu/menu.html'
})
.state('menu.content', {
views: {
'default': {
url: '/default',
template: '<h1>Please select something</h1>'
},
'content1': {
url: '/content1',
templateUrl: 'app/content1/content1.html'
},
'content2': {
url: '/content2',
templateUrl: 'app/content2/content2.html'
}
}
});
As you can see very clear to read and understand from url what is inside and why. If you will have url menu/content1 - that's mean under your menu is content1 visible right now.
You don't have to define another state for the the menu just add it to your home state as another view. Like this
.state('home', {
url: '/home',
views:{
'menu': {
templateUrl: 'app/menu/menu.html'
},
'home': {
templateUrl: 'app/home/home.html'
}
}
})
And change your HTML to this:
<div ui-view="menu"></div>
<div ui-view="home"></div>
And whenever you want to update the view (keeping the menu the same), create a state for that view like this:
.state('home.newState', {
url: '/newState',
views:{
'home#':{
templateUrl: 'app/home/newState.html'
}
}
})
This will update the view by adding the newState.html template in place of home.html template keeping the menu same.

how to change the templateUrl of a state upon authentication in angularjs

here i have a neatly configured routing pattern in ui.route
'use strict';
var app = angular.module('myApp', [ 'ngAnimate', 'ui.router']);
app.config([ '$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state('App', {
url : '/',
views : {
'header' : {
templateUrl : 'partials/header.jsp',
controller : 'headerController'
},
'body' : {
templateUrl : 'partials/indexbody.jsp',
controller : 'indexBodyController'
},
'footer' : {
templateUrl : 'partials/footer.jsp'
}
}
}).state('App.Dashboard', {
url : 'Dashboard',
views : {
'body#' : {
templateUrl : 'partials/dashboard.jsp',
controller : 'dashboardController'
},
'dashboardBody#App.Dashboard' : {
templateUrl : 'partials/dashboard_adddeal.jsp'
}
}
}).state('App.Dashboard.AddDeal', {
url : '/AddDeal',
views : {
'dashboardBody#App.Dashboard' : {
templateUrl : 'partials/dashboard_adddeal.jsp'
}
}
}).state('App.Dashboard.Section2', {
url : '/Section2',
views : {
'dashboardBody#App.Dashboard' : {
templateUrl : 'partials/a.html'
}
}
});
} ]);
Everything is working fine, but i want to change the "body-view" in 'App' State After the authentication is successful
to simply put it i want to show a different state after authentication.
im new to angular, so go easy on me ;)
The solution will be dependent on how you have implemented your authentication, but there are a couple of ways to dynamically specify a template.
templateUrl can be a function which takes one parameter,$stateParams, and returns a URL
Alternatively, templateProvider can be a function with injected parameters that returns template HTML.
Detail here: https://github.com/angular-ui/ui-router/wiki#templates
With that said, I would exercise caution with either of these paths. If the user's authentication status changes without a state change, the template in use may not be updated.
You can use the resolve promise on your $stateProvider.state call.
Ex:
.state('App', {
url: '/',
/*some skipped lines*/
resolve: {
/*verify the authentication*/
verify();
$state.go('App.Dashboard');
}
});
More details about you can do in here: https://github.com/angular-ui/ui-router/wiki/Quick-Reference#resolve

Angular JS URL rewriting issues

I am currently working on an Angular app and facing some issues with URLs.
Problem:
My application has the main page which has multiple sections and all sections fetch data from backend. There is an animated scroller on each section, e.g. If I am at section1 and select Section3, it scrolls me to Section3 in a nice animated way. I have few pages which also are fetched from backend but totally changes the view. This is the hierarchy of views:
Page1:
Section1, Section2, Section3, Section4, Section5 (Will be visible in whole application aka HEADER)
Section5:
Link1, Link2 (Each link is totally a separate view)
If I am on Link1 and click any of the Section, it appends # to the URL relatively and doesn't redirect me to the actual section.
Question(s):
I do not want to use # anywhere at all, how can I get rid of it?
I do not want to remove animation from my home page.
If I am on some other view and click on any section (HEADER), it should take me to that particular position, how can I achieve this?
This is my routes.js file:
var webApp = angular.module('webApp', ['ngRoute','ngSanitize']);
webApp.config(function($routeProvider, $locationProvider) {
if(window.history && window.history.pushState) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
}
$routeProvider
.when('/', {
templateUrl : 'application/header.jsp',
controller : 'homeController'
})
//section2
.when('/section2', {
templateUrl : 'application/header.jsp',
controller : 'homeController'
})
.when('/section3', {
templateUrl : 'application/header.jsp',
controller : 'homeController'
})
.when('/section4', {
templateUrl : 'application/header.jsp',
controller : 'homeController'
})
.when('/section5', {
templateUrl : 'application/header.jsp',
controller : 'homeController'
})
.when('/section7', {
templateUrl : 'application/header.jsp',
controller : 'homeController'
})
.when('/section8', {
templateUrl : 'application/header.jsp',
controller : 'homeController'
})
.when('/Link1', {
templateUrl : 'application/link1.jsp',
controller : 'link1Controller'
})
.when('/Link2', {
templateUrl : 'application/link2.jsp',
controller : 'link2Controller'
})
.when('/Link3', {
templateUrl : 'application/link3.jsp',
controller : 'link3Controller'
});
});
Any help will be greatly appreciated or if anything is missing or required, please do let me know.

angular-ui-router blank page with index.html in URL

I use angular 1.1.5 and ui-router. My Spring-based webapp is reachable at http://mydomain:8080/webapp/app/index.html
All the resource files are loaded, and when angular bootstrap the main module, the URL is changed to http://mydomain:8080/webapp/app/index.html#/index.html and the page is blank.
ui-router is configured as
myapp
.config(function($stateProvider) {
$stateProvider
.state('layout', {
abstract : true,
views : {
"headerView" : {
templateUrl : 'partials/header.html',
controller : 'LoginController'
},
"navigationView" : {
templateUrl : 'partials/navigation.html',
controller : 'NavigationController'
}
}
})
.state(
'layout.home',
{
url : "", // root route
views : {
"contentView#" : {
templateUrl : 'partials/content.html',
controller : function() {
console.log("Root URL");
}
}
}
});
I tried to create a plunker to show the issue but I did not succeed.
Add url:'/' to the base abstract view.
.state('layout', {
abstract : true,
url:'/',
views : {
"headerView" : {
templateUrl : 'partials/header.html',
controller : 'LoginController'
},
"navigationView" : {
templateUrl : 'partials/navigation.html',
controller : 'NavigationController'
}
}
})

Resources