Note: I am using AngularJS v1.6.0
I have implemented a stand-alone AngularJS app into another existing website, it exists on a single page on the site and the rest of the site doesn't have any Angular code running on it.
For example, a regular page on the site could be at:
http://example.com/any-page
Then the user can click on a link and it takes them to the page with the Angular JS running on it:
http://example.com/angularjs-app
When landing on this URL it loads the AngularJS app and appends #!/
to the URL as expected. It doesn't contain any elements from the rest of the site such as the header, so for the user it looks like a completely different section. However it also breaks the back button. It's not possible press back to go back to http://example.com/any-page
. Each time you press back, it just loads the landing view of the AngularJS app again - effectively the user is stuck on the AngularJS app page and cannot go back to /any-page
.
I think this has something to do with AngularJS routing, because it seems to refresh the #!/
portion of the URL when you press back, and just reload the initial view on the app. But I could be wrong.
Note that the back button works fine within the AngularJS app when visiting various routes. For example, if I navigate between various routes/views in the app, such as #!/login
or #!/view-details
, I can always go back through these views via the back button. But when it reaches that initial view, it stops working.
Does anyone know a way around this?
Note: I have looked at various other Stack Overflow posts on this, however they all seem to be concered with the back button not working at all, rather than this issue where the back button works for navigating between routes within the app, but not back to the original non-AngularJS page on the site.
Routing config
(function () {
"use strict";
var routes = {
error: "/error",
forgottenPassword: "/forgotten-password",
home: "/home",
login: "/login",
orders: "/orders",
paymentDetails: "/payment-details",
personalDetails: "/personal-details",
subscriptions: "/subscriptions",
updatePassword: "/update-password",
accountVerification: "/account-verification",
register: '/register',
profile: '/profile',
accountConfirm: '/account-confirm',
deleteAccount: '/delete-account'
};
var configFunc = function (
$routeProvider,
$locationProvider,
CONFIG,
ROUTES) {
var resolve = {
isLoggedIn: [
"$q", "ERRORS", "core.services.sessionsService", function ($q, ERRORS, sessionsService) {
return sessionsService.isLoggedIn().then(function (isLoggedIn) {
if (isLoggedIn) {
return isLoggedIn;
}
return $q.reject({ error: ERRORS.route.requiresAuth });
});
}
]
};
var getTemplateUrl = function(page) {
return CONFIG.rootPagesUrl + page;
};
$routeProvider
.when("/", {
controller: "StartCtrl",
template: ""
})
.when(ROUTES.login, {
templateUrl: getTemplateUrl("login.html"),
pageName: "Login"
})
.when(ROUTES.forgottenPassword, {
templateUrl: getTemplateUrl("forgotten-password.html"),
pageName: "Forgotten Password"
})
.when(ROUTES.home, {
templateUrl: getTemplateUrl("home.html"),
resolve: resolve
})
.when(ROUTES.personalDetails, {
templateUrl: getTemplateUrl("personal-details.html"),
resolve: resolve
})
.when(ROUTES.paymentDetails, {
templateUrl: getTemplateUrl("payment-details.html"),
resolve: resolve
})
.when(ROUTES.orders, {
templateUrl: getTemplateUrl("orders.html"),
resolve: resolve
})
.when(ROUTES.subscriptions, {
templateUrl: getTemplateUrl("subscriptions.html"),
resolve: resolve
})
.when(ROUTES.updatePassword, {
templateUrl: getTemplateUrl("update-password.html"),
pageName: "Update Password"
})
.when(ROUTES.accountVerification, {
templateUrl: getTemplateUrl("account-verification.html"),
pageName: "Account Verification"
})
.when(ROUTES.error, {
templateUrl: getTemplateUrl("error.html"),
pageName: "Error"
})
.when(ROUTES.register, {
templateUrl: getTemplateUrl("register.html"),
pageName: "Register"
})
.when(ROUTES.profile, {
templateUrl: getTemplateUrl("profile.html"),
resolve: resolve,
pageName: "Profile"
})
.when(ROUTES.accountConfirm, {
templateUrl: getTemplateUrl("accountConfirm.html"),
pageName: "Registration Complete"
})
.when(ROUTES.deleteAccount, {
templateUrl: getTemplateUrl("deleteAccount.html"),
resolve: resolve,
pageName: "Delete Account"
})
.otherwise({
templateUrl: getTemplateUrl("login.html"),
pageName: "Login"
});
};
var config = [
"$routeProvider",
"$locationProvider",
"CONFIG",
"ROUTES",
configFunc
];
var module = angular.module("app");
module.constant("ROUTES", routes);
module.config(config);
})();
Portion of index where ng-view lives:
<body ng-app="app" ng-strict-di>
<div>
<div id="container" class="mpp-app">
<div class="mpp-page" id="mpp-page">
<div class="page-wrapper">
<div class="ui-module-container">
<div brand></div>
</div>
<div ng-view></div>
</div>
</div>
<div class="ui-module-container">
<div footer></div>
</div>
</div>
</div>
<div id="spinner" class="hidden"><div class="icon"></div></div>
StartCtrl
(function () {
"use strict";
var func = function (
$rootScope,
$scope,
$location,
ROUTES,
APP_EVENTS,
CORE_EVENTS,
SessionModel,
sessionsService,
configurationAggregator) {
var broadcast = function(event, args) {
$rootScope.$broadcast(event, args);
};
var redirectToLogin = function() {
broadcast(APP_EVENTS.navigation.login);
};
// check if user is signed in and has a valid session
var verifySession = function() {
sessionsService.verify().then(function() {
// if user is logged in navigate to profile
// otherwise navigate to login
configurationAggregator.getConfiguration().then(function () {
broadcast(APP_EVENTS.auth.login.success);
//broad cast(APP_EVENTS.navigation.home);
broadcast(APP_EVENTS.navigation.uktvProfile);
}, redirectToLogin);
}, redirectToLogin);
};
// init
var sessionId = $location.search().guid;
if (angular.isDefined(sessionId) && sessionId !== null) {
broadcast(CORE_EVENTS.session.changed, { sessionId: sessionId });
verifySession();
} else {
verifySession();
}
};
var controller = [
"$rootScope",
"$scope",
"$location",
"ROUTES",
"EVENTS",
"mpp.core.EVENTS",
"mpp.core.SessionModel",
"mpp.core.services.sessionsService",
"mpp.core.aggregators.configurationAggregator",
func
];
var module = angular.module("app");
module.controller("StartCtrl", controller);
})();
It is not an issue of the AngularJS Router (although might be a bug of the specific version, so please add information about the version to the question). But most likely you have a redirect in a router event(s)' handler, or in StartCtrl
.
The example from the AngularJS tutorial works fine, you can get it here:
git clone https://github.com/angular/angular-phonecat.git
To localize the issue i would first try to run your app with following config:
$routeProvider
.when('/', {
template: '<div>Hello</div>'
})
.when(ROUTES.login, {
templateUrl: getTemplateUrl("login.html"),
pageName: "Login"
})
.when(ROUTES.forgottenPassword, {
templateUrl: getTemplateUrl("forgotten-password.html"),
pageName: "Forgotten Password"
})
.when(ROUTES.home, {
templateUrl: getTemplateUrl("home.html"),
resolve: resolve
})
.when(ROUTES.personalDetails, {
templateUrl: getTemplateUrl("personal-details.html"),
resolve: resolve
})
.when(ROUTES.paymentDetails, {
templateUrl: getTemplateUrl("payment-details.html"),
resolve: resolve
})
.when(ROUTES.orders, {
templateUrl: getTemplateUrl("orders.html"),
resolve: resolve
})
.when(ROUTES.subscriptions, {
templateUrl: getTemplateUrl("subscriptions.html"),
resolve: resolve
})
.when(ROUTES.updatePassword, {
templateUrl: getTemplateUrl("update-password.html"),
pageName: "Update Password"
})
.when(ROUTES.accountVerification, {
templateUrl: getTemplateUrl("account-verification.html"),
pageName: "Account Verification"
})
.when(ROUTES.error, {
templateUrl: getTemplateUrl("error.html"),
pageName: "Error"
})
.when(ROUTES.register, {
templateUrl: getTemplateUrl("register.html"),
pageName: "Register"
})
.when(ROUTES.profile, {
templateUrl: getTemplateUrl("profile.html"),
resolve: resolve,
pageName: "Profile"
})
.when(ROUTES.accountConfirm, {
templateUrl: getTemplateUrl("accountConfirm.html"),
pageName: "Registration Complete"
})
.when(ROUTES.deleteAccount, {
templateUrl: getTemplateUrl("deleteAccount.html"),
resolve: resolve,
pageName: "Delete Account"
})
.otherwise({
templateUrl: getTemplateUrl("login.html"),
pageName: "Login"
});
If it works properly then you have something fishy going on in the StartCtrl controller. If still doesn't work properly, try this:
$routeProvider
.when('/', {
template: '<div>Hello</div>'
})
.otherwise('/');
If works properly then look for $routeChangeError
handlers. If not then might be any router event handler. Here is the list of event for the ngRoute: $routeChangeStart
, $routeChangeError
, $routeUpdate
, $routeChangeSuccess
EDIT:
Since you don't want users to return back to /
route when they click go back you can remove it from history. Just call replace method on $location
service when you redirect users away from /
route. E.g. $location.path('/login').replace()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With