Search code examples
javascriptangularjsbrowser-historyhtml5-history

History API/Angular: how to go back to predetermined URL


I have a requirement within my Angular app which uses the Angular UI Router, to go back from one screen (URL) to a previously visited screen (URL). There are several screens (URLs) where it's possible to visit the destination page. It's not quite as straight forward as a simple history.back() operation though` because I have several interim states that can occur in any order and any number. To get around this I have implemented a wrapper around the Angular $location service, like so:

(function () {
    'use strict';
    angular
        .module('myApp')
        .factory('locn', ['$location', '$state',
            function ($location, $state) {
                var states = [];
                return {
                    go: function (url) {
                        $location.path(url);
                    },
                    pushandgo: function (state, params) {
                        states.push({ name: $state.current.name, params: $state.params });
                        $state.go(state, params);
                    },
                    push: function (url) {
                        states.push(url);
                    },
                    pop: function () {
                        var state = states.pop();
                        $state.go(state.name, state.params);
                    },
                    search: function (searchDict) {
                        $location.search(searchDict);
                    }
                };
            }]);

})();

As you can see, this stores the state in a javascript local variable of the locn service. I can call pushandgo and that means when I subsequently call pop I can return to the page I came from (regardless of what page that was).

This works OK, until the user refreshes the page when they are on the destination page.

The states array is recreated loosing all previously pushed states.

I'm struggling to come up with a nice solution to this other than using cookies or local storage (yuck).


Solution

  • I've found a more palatable solution to using cookies or local storage - session storage!

    My locn service now looks like this.

    (function () {
        'use strict';
        angular
            .module('csApp')
            .factory('locn', ['$location', '$state', '$window',
                function ($location, $state, $window) {
                    return {
                        go: function (url) {
                            $location.path(url);
                        },
                        pushandgo: function (state, params) {
                            $window.sessionStorage.setItem("prev", JSON.stringify({ name: $state.current.name, params: $state.params }));
                            $state.go(state, params);
                        },
                        pop: function () {
                            var state = JSON.parse($window.sessionStorage.getItem("prev"));
                            $window.sessionStorage.removeItem("prev");
                            $state.go(state.name, state.params);
                        },
                        search: function (searchDict) {
                            $location.search(searchDict);
                        }
                    };
                }]);
    
    })();