Search code examples
testingember.jsurl-routinghtml5-history

Access browsing history in ember


I have the following two paths to edit an object (node) in my application:

  1. List nodes -> click edit icon
  2. List nodes -> select node -> click edit button

I have the option to cancel the editing. When I cancel, I want the router (controller?) to go back to the right place. That is, if I came from the list of nodes, I want cancel to go back to "list of nodes" (#nodes). If I came from the node view, I want cancel to go back to the node view (#nodes/show/node-id). Currently this is the implementation in my NodesEditController:

SettingsApp.NodesEditController = Ember.ObjectController.extend({
    needs: ['nodesIndex'],
    selectedNode: null,
    selectedNodeType: null,
    nodes: [],
    ...
    cancel: function () {
        this.stopEditing();
        this.transitionToRoute('nodes.show', this.get('content'));
    },

    ...
});

As you can see, the route for the cancel action is fixed (nodes.show). But in the first case, I would like to do this.transitionToRoute('nodes.index');. So my cancel method must be something like this:

 cancel: function () {
    this.stopEditing();
    if (some_test) { this.transitionToRoute('nodes.show', this.get('content'));
    } else { this.transitionToRoute('nodes.index'); }
 }

How to implement some_test? What can I test to know how did I get to the current route?


Solution

  • Reopen Ember.Route to store the currentPath when a route is exited:

    Ember.Route.reopen({
      deactivate: function() {
        var applicationController = this.controllerFor('application');
        App.previousPath = applicationController.get('currentPath');
      }
    });
    

    Then in your cancel method:

    goBack: function () {
        if (SettingsApp.previousPath == 'nodes.show') {
            this.transitionToRoute(SettingsApp.previousPath, this.get('content'));
        } else {
            this.transitionToRoute(SettingsApp.previousPath);
        }
    },
    
    cancel: function () {
        this.stopEditing();
        this.goBack();
    },
    

    Note: you might want to provide some fallback in case the app is loaded in the nodes.edit route.