Search code examples
ember.jsroutesbrowser-history

EmberJS: how to know if route was called because the user clicked the Back button


I need to know whether my route was called because the user clicked the browser Back button instead of clicking a {{link-to}} link to get there. The reason for this is because of I have a filterable list with pagination on the associated template for that route. If the user navigates away from this list and then clicks the back button, my designer wants the state of the filters to be in tact. However, if the users clicks a link to arrive at this list, my designer wants the filter and pagination to be reset.

Example:

1) Users clicks the 'Books' navigation link and arrives at '/books'.
2) User filters the list goes to page 2 of results.  This does not update the URL and user is still at '/books'.
3) User clicks one of the Books and goes to '/books/123'.
4) User clicks the browser Back button and goes back to '/books'.  I need to show the filtered list at page 2.
5) User clicks the 'About Us' link and goes to '/about'
6) User clicks the 'Books' navigation link and arrives at '/books'.  But this time, the user didn't click the browser Back button to arrive here, so I need to reset the filters and show a list of unfiltered Books on page 1.

In both step 4 and step 6, the user arrives at '/books' and BooksRoute, but the mechanism they used to arrive there differs, so I need to show a different books list result. Is there a way to tell if a Route was called because the Back button was clicked instead of clicking a hyperlink?


Solution

  • Without saving state in the url, I'd probably create a dummy route that eliminates books state when accessed through that link. (I assume the controller is where you're keeping track of this state).

    Router

    this.resource('books', function(){
      this.route('all');    
    });
    

    Route

    App.BooksAllRoute = Em.Route.extend({
      setupController: function(){
        var booksController = this.controllerFor('books');
        booksController.set('filters', {});
        // replaceWith replaces the history instead of adding additional history
        // this may not be necessary since we're doing it mid transition
        // this.transitionTo may be more appropriate
        this.replaceWith('books');
      }
    });
    

    Template

    {{link-to 'Books' 'books.all'}}
    

    You might need to move the dummy route to the same level in the router so as to avoid having the books model already being populated. (I'm guessing about how you're actually filtering your results)