Save and restore previous state on cancel

I would like to be able to remember a previous state just before transitioning so that if I hit cancel on a form I can restore the previous state.

/users/1 => new => /users/create => cancel => /users/1

How do I do this?

Controllers are singletons, and the controller for users/:user and users/create are different, so if you navigate back to users/:user from your users/create route and don’t pass it a model, it should be exactly as you left it.

That’s exactly my problem. Since I do not know that I came from /users/1 then I cannot go back using transitionTo.

Ah, good point. Some ideas:

  • It’s a little hacky, but you could use the window.back() method.

  • It might affect your UX in ways that you don’t want, but you could also have such a form as a modal, where you never actually leave the current route. The modal example on the Ember site is a good example of how to do this.

  • Alternatively, you could probably modify the use case for the last example in the transitions guide.

make the cancel an action, do record.rollback(); and then the transition wherever you like with this.transitionToRoute

What then do I pass to this.transitionToRoute when I do not know from which route I came?

I am exactly in the same situation, with the added challenge that the suggestion of @kylecoberly window.location.back() doesn’t work as well as it should, since it triggers an unwanted request of the store model.

The other suggestion he made of using a modal is currently the most viable I’ve seen.

Have a look at this approach, maybe that already helps

The link is interesting, but basically it returns the same thing as logging does, e,g,

/users/4 => Transitioned into 'users.user.index'
/users/create => Transitioned into 'users.create'

The problem still being that I’ve lost reference to users id = 4 which is alos needed to call:

this.TransitionTo('users.user', user)

Maybe I’m just approaching this whole thing wrong …

An idea:

Should the changes you want to remember be persisted between browser refreshes? If that’s the case, you should save them in the model when you go to the create page, and then when you navigate back to that route it will read the data as it was. As far as remembering that you were on user 4, you could always do something like this:

//Application controller
currentUser = null

//Users controller
needs: ["application"],
someFunctionToCallWhenYouLeave: function(){
    this.set("controllers.application.currentUser", this.get("id"));

//Create controller
needs: ["application"],
someFunctionToCallWhenYouCancel: function(){
    this.transitionToRoute("users", this.get("controllers.application.currentUser");

I’ve created a small app which replicates some of the behavior, welcoming suggestions on how to improve.

in the ‘back’ action on search is where the problem arises. window.location.back() seems like an OK solution at first, but not if your model is a promise which only resolves later.

This seems to me to be a fundamental shortcoming of the architecture. I would be eager to explore a more elegant way to implement such a basic feature:

I am here: url_A
Go there: url_B
If cancel then go back to url_A.

Where url_A and url_B do not have to be related to each other in anyway, So for example, we could have:

url_A => /users/5/foo
url_B => /channels/create

Absolutely, but, even more fundamentally, going back to a URL does not even cover most cases, since it is another transition which is not always required.

Modals, as suggested earlier, help quite a bit, but aren’t game-changing unfortunately when not knowing what controllers and templates to re-activate.

Did you try the solution from @kylecoberly? That should work. Until you change your users.user model, it will have a reference to the last user.