Confirming Actions in Ember

chrsmllr
3 min readFeb 11, 2019

--

I’ve been working in Ember a lot lately, and recently there was a request to recreate functionality similar to window.confirm(), where the user would be asked whether they actually want to delete a record.

💭 window.confirm() is one of the many super useful UI patterns that javascript gives us out-of-the-box. While I usually like to avoid re-implementing things that the browser gives us for free, I saw this as a great opportunity to leverage some cool Ember features. And hey, we’ll get a prettier UI for it as an added bonus ✨

Rather than building out the feature for this specific use case, I decided, why the heck not. Let’s take a swing at making it reusable, and implement it using a service.

My initial inspiration came from the wonderful addon ember-cli-flash, which takes the approach where a service manages the state, and the user is responsible for rendering the UI within the topmost application template.

First thing’s first, lets set up the service:

The most important method above: ask() . Here we pass along a message and title for the modal prompt we’ll show to the user. Within our service, this method sets showPrompt to true, and sets up a promise deferral, via Ember.RSVP.defer.

A deferred promise gives us a lot of power here. Calling this method will return a promise. But, that promise will neither resolve nor reject until we tell it to.

For this example, we’ll do so by way of a “Confirm” or “Cancel” button in a modal. (ahem — very similar to our BFF window.confirm()). The actions confirm and cancel in our service will both generally do the same thing, resolving our promise and resetting our private _deferral property back to null. To keep parity with window.confirm, we’ll resolve regardless, but return a boolean based on which was called.

Next, our template. We’ll use ember-modal-dialog for our modal here, to keep things clean:

Not shown: Injecting our confirm-action service into our application controller.

And voila! We’ve got the groundwork laid to use our confirm-action service. Simple, right? Rendering a modal in the application template ensures that it does not have to fight with z-indexes to be the foremost element in the DOM.

And now, lets see it in action:

Not shown: The button within our template which calls {{action deleteRecord}}

On line 10, we call our ask() method, with the messaging we’d like to display to the user, and await the user’s response, to be stored in our result variable.

This method will not resume to line 15 until the user has clicked one of the two buttons in our modal, which resolve the deferred promise we returned.

And thats about it! We’ve successfully leveraged an Ember service in order to create a super easy-to-use way to confirm an action. Like I said above, javascript gives us some pretty neat stuff out of the box, which, by all means — If you can use it, PLEASE DO! But Ember provides some great tools to achieve similar functionalities with little boilerplate.

Feel free to leave a comment with further questions, and I’m always down to hear of improvements that can be made! 🤓

--

--