ui-router doesn't change browser url with default params - angularjs

I actually have two problems.
Here is a state:
$stateProvider.state('detail', {
url: '/detail?query',
params: {query: 'abc'}
templateUrl: 'views/detail.html',
controller: 'DetailCtrl'
})
If I go to /detail, $stateParams.query is indeed set to abc. However, browser URL is still /detail, rather than /detail?query=abc (what we want).
What we currently do is call $location.search('query', 'abc') when DetailCtrl loads. However, when back button is clicked at /detail?query=abc, the browser goes back to /detail.
Expected behavior:
Go to /detail, browser should automatically set URL to /detail?query=abc.
Click back button at /detail?query=abc, browser should go back to the page before /detail.

Related

Override back button to go to specific state using Angular UI Router

I have an Angular app with various different states defined. I do not want the user to be able to go back to previous states using the back button, as they are part of a simulation and it disturbs the simulation flow.
Is there a way I can override the browser back button to take users to the starting state of the simulation?
angular.module('participant').config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('simulations', {
url: '/',
controller: 'SimulationIndexController',
templateUrl: '/angular_templates/simulations/index.html',
})
.state('simulation.content', {
// other routes
});
I want to go to the 'simulations' state when the user presses the back button on the browser but I am not sure how to accomplish this.
Use location: 'replace' when doing state transitions:
$state.go("simulation.content.state2",{location:'replace'});
By using the replace option, the individual simulation steps will not be stored in the browser history. When the user hits the back button, the user will be taken back to the beginning instead of the previous content.
You could add on top
.run(function($state) {
$(window).on('popstate', function(event) {
// This event fires on current history change
$state.go("simulations");
}, false);
})

Navigate back to state without reloading template

I have done some research but couldn't find a definitive answer. I have main application area where I load different screens. From one screen I want to open a page that would cover the whole screen. So, navigating to 'viewreport' does exactly that. And when I click on Browser's Back button or have my own Back button on the whole screen page I want to get back to the previous state without reloading its template and controller. Another words, I want to see all selections I have done prior opening the whole screen page. Here is my state configuration:
$stateProvider
.state('body', {
url: '/',
abstract: true,
template: '<div ui-view />'
})
.state('viewreport', {
url: 'viewreport',
templateUrl: 'wholescreen.html',
controller: 'wholescreenController'
});
I am loading different modules into the main 'body' state which might look like this:
function ($stateProvider) {
$stateProvider.state('body.htmlreports', {
templateUrl: function ($stateParams) {
return 'htmlReports.html';
},
controller: 'htmlReportsController',
url: 'htmlreports',
}).state('body.htmlreports.reportarea', {
templateUrl: 'htmlReportParams.html',
controller: 'htmlReportParamsController',
});
I am navigating to viewreport state from htmlReportParamsController controler. The new page then opens into the whole screen. That part works fine. But navigating back to htmlreports when clicking on the Browser's Back button will reload 'body.htmlreports' state. Is there a way of getting back to it without reloading its template?
Update. Why I think it's not a duplicate.
I tried what's suggested in it before posting. This: $state.transitionTo('yourState', params, {notify: false});
still reloads 'yourState'. Also the use case in the provided link is not exactly as mine. Because the OP uses edit mode for already loaded view while I am loading a new view over the the whole screen.
Thanks
Use
$window.history.back();
Add $window in dependency injections of your controller. This will refresh your page and wont reload data we selected.
Please maintain states like this
function ($stateProvider) {
$stateProvider.state('body.htmlreports', {
templateUrl: function ($stateParams) {
return 'htmlReports.html';
},
controller: 'htmlReportsController',
url: 'htmlreports',
}).state('body.htmlreports.reportarea', {
templateUrl: 'htmlReportParams.html',
controller: 'htmlReportParamsController',
}).state('body.htmlreports.reportarea.viewreport', {
url: 'viewreport'
});

Issue with $state.go() transitions, only on second click

I have a issue with ui-router which I can't quite put my finger on. I can click on a link (on the login page of my app) and navigate to a second page (one where the user can register). There is a cancel button on the second page which simply navigates the user back to the first page. All good so far.
If I then click on the same link again, the user appears to stay on the same page (i.e. the login page), however I have added a 'state change' handler to my app (it just logs the transition to the console) and can see that what actually happens is that the app seems to transition to the second page and then back again. The following won't make much sense other than to demonstrate the flow. You can see the state change start, end and the view load before it starts again and transitions back to 'authentication.login'
Start state change : {authentication.login} to {authentication.registration}
View content loading
End state change success : {authentication.login} to {authentication.registration}
View content loaded
Start state change : {authentication.registration} to {authentication.login}
View content loading
End state change success : {authentication.registration} to {authentication.login}
View content loaded
NOTE: both pages are siblings of the same abstract node.
Any ideas why this might be happening?
NOTE: state config is as follows
.state("authentication", {
url : "/auth",
abstract : "true",
templateUrl : "app/main/common/html/templates/simple-template.html",
})
.state("authentication.login", {
url: "/login",
views: {
"main": {
templateUrl : "app/main/authentication/html/login.html",
controller: "LoginController"
}
}
})
.state("authentication.registration", {
url: "/registration",
views: {
"main": {
templateUrl : "app/main/authentication/html/registration.html",
controller: "RegistrationController"
}
}
})
do you have any
rootScope.$on('$stateChangeStart'
logic in your app that is causing the state transition.
Usually logic will be put in here to kick a user back to the login page if the user is not auth'd
a wild guess but the best guess i can make given the information provided.
thanks
another idea, if you remove the state change handler does everything work ok?

$location.path() is navigating to some other page

I have below states defined-
.state('HomePage', {
url: '/HomePage',
templateUrl: 'home.html',
controller: 'HomeCtrl'
})
.state('RegistrationHome', {
url: '/RegisterHome',
templateUrl: 'RegistrationHome.html',
controller: 'RegistrationHomeCtrl'
})
.state('RegisterAdditionalInfo', {
url: '/RegisterAdditional',
templateUrl: 'RegistrationAdditional.html',
controller: 'RegistrationAddCtrl'
})
From home page when I click on register button, I will be navigating to registration home page using $location.path('/RegisterHome');
Now on registration home page I provide my email Id and username and click on continue button. After clicking on continue button it provides additional fields (Age and Gender) to be filled on the same page. On click of continue $location.path('/RegisterHome/RegisterAdditionalInfo') is loading the RegistrationAdditional.html. Age and Gender are present in RegistrationAdditional.html.
Now there is one 'Cancel' button. If I click on 'Cancel' button I want to go to HomePage. On click of cancel I am calling one function in the controller and in this function I am writing
$location.path('/HomePage'); for navigation. But it's not navigating to HomePage. On click of cancel it's navigating to 'RegistrationHome'.
In url function ($location.url()) I tried to print the url. On click of 'cancel' , url is 'HomePage' but again url function is being called automatically and url value is getting changed to 'RegistrationHome'. I tried all possible ways like writing $scope.$apply() after $location.path('/HomePage'), using $state.go('HomePage') instead of $location.path('/HomePage'); but nothing worked. Could someone plz help me on this.

Ui-router: how to block url navigation but accept state navigation

I try to do some functionality that accepts a state navigation (using $state.go(otherState)), refreshing the associated url in the adress/url bar but it blocks (or redirects to not allowed page) if user directly puts this url in the adress/url bar.
Could it be done by ui-router rules or something inside ui-router module?
I put the example code:
$stateProvider.state("main", {
url: "/index.html",
templateUrl: "main.html"
}).state("notAccessibleScreenByBar", {
url: "/private/example.html",
templateUrl: "example.html"
});
From main view (index.html), the next angular code will be executed:
$state.go("notAccessibleScreenByBar");
This action changes the view, loading example.html and refreshing the url bar to /private/example.html.
If user puts /private/example.html in the adress/url bar, ui-router must block this request (or redirect to not-allowed page).
What you are trying to do seems very similar to any web authentication standard, but, if you don't want that, you could use $locationChangeSuccess (docs here)
A basic example inspired by this sample:
$rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
// Prevent $urlRouter's default handler from firing
e.preventDefault();
if(isThisTransitionValid(newUrl, oldUrl)) {
// Ok, let's go
$urlRouter.sync();
});
});

Resources