# Window.confirm without native code?

**URL:** <https://discourse.elm-lang.org/t/window-confirm-without-native-code/844>\
**Category:** Learn\
**Created:** [March 12, 2018, 6:22pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844 "2018-03-12T18:22:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![xtian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/xtian/32/1178_2.png) [@xtian](https://discourse.elm-lang.org/u/xtian)\
**Post date:** [March 12, 2018, 6:22pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/1 "2018-03-12T18:22:17Z")

</div>

In our application we currently have a native shim to allow calls to `window.confirm`.

It looks like this:

```javascript
window._xtian$someApp$Native_Utils_Window = {
  confirm: window.confirm
};

```

If we wanted to migrate away from this solution to be compatible with 0.19, what would be the best approach?

---

<div class="post-metadata">

**Author:** ![rtfeldman](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rtfeldman/32/50_2.png) [@rtfeldman](https://discourse.elm-lang.org/u/rtfeldman)\
**Post date:** [March 12, 2018, 6:29pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/2 "2018-03-12T18:29:52Z")

</div>

If I were using `window.confirm`, my personal preference would be to migrate to a nicer alterative for my users, since [more user-friendly confirmation dialogs](https://stackoverflow.com/questions/2577128/why-javascript-dialogs-alert-prompt-confirm-are-not-widely-used-and-not-under) can be implemented using plain old DOM nodes.

Is there a reason that approach wouldn’t be possible?

---

<div class="post-metadata">

**Author:** ![xtian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/xtian/32/1178_2.png) [@xtian](https://discourse.elm-lang.org/u/xtian)\
**Post date:** [March 12, 2018, 6:36pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/3 "2018-03-12T18:36:31Z")

</div>

Actually all of the user-hostile behavior that `window.alert` and `window.confirm` used to have has been improved in modern browsers. A StackOverflow post from 2010 is perhaps not the best resource for this information.

For instance: [https://developers.google.com/web/updates/2018/01/nic64#window-alert](https://developers.google.com/web/updates/2018/01/nic64#window-alert)

For simple use-cases, `window.confirm` is a cheap and easy solution that is guaranteed to be accessible and consistent with the browser UI.

So is there a good way to use `window.confirm` with Elm?

---

<div class="post-metadata">

**Author:** ![evancz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/evancz/32/16_2.png) [@evancz](https://discourse.elm-lang.org/u/evancz)\
**Post date:** [March 12, 2018, 7:12pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/4 "2018-03-12T19:12:01Z")

</div>

Is this one of those things that can only be called if the event loop began with a user input? If so, I believe the reason ports do not work at the moment is that the current releases uses `requestAnimationFrame` before showing things, thereby cutting the event provenance needed for this sort of thing. Is that correct?

I modified virtual-dom to allow people to respond directly to user input events. That means:

1. The issue where changing `<input value="blah">` too quickly can get lost will be gone. It will be synchronous now. The idea being that user inputs like typing are slow enough that it’s fine if it is not synced with animation frames.
2. If people need to do “only on user event” actions, they can do it through ports.

That required a breaking change in `virtual-dom` to `on` that will come out with 0.19. It is just a bit more flexible (to cover “passive events” as well) so any existing uses should need only tiny tweaks.

Anyway, I think that handles your other question as well, but I’m not 100% certain I diagnosed the root problem correctly in your specific cases. If it does handle the other question as well, can someone make a note over there?

---

<div class="post-metadata">

**Author:** ![joelq](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joelq/32/445_2.png) [@joelq](https://discourse.elm-lang.org/u/joelq)\
**Post date:** [March 12, 2018, 7:19pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/5 "2018-03-12T19:19:00Z")

</div>

Here’s an [implementation using ports](https://ellie-app.com/9m6HBwJ8Ga1/0). I don’t think it triggers the issues discussed by @evancz above.

---

<div class="post-metadata">

**Author:** ![xtian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/xtian/32/1178_2.png) [@xtian](https://discourse.elm-lang.org/u/xtian)\
**Post date:** [March 12, 2018, 7:20pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/6 "2018-03-12T19:20:44Z")

</div>

I’m not sure about the event loop question because we didn’t get to that point.

The difficulty we had with ports was that there was no way to associate the message coming back into the Elm app with the user input that triggered the `window.confirm`.

We could have tried generating a unique ID to send back with the boolean result of the dialog, but that felt like a lot of complex harness for a problem that could be safely solved with three lines of native code.

---

<div class="post-metadata">

**Author:** ![xtian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/xtian/32/1178_2.png) [@xtian](https://discourse.elm-lang.org/u/xtian)\
**Post date:** [March 12, 2018, 7:22pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/7 "2018-03-12T19:22:41Z")

</div>

> [@joelq](#):
>
> Here’s an implementation using ports. I don’t think it triggers the issues discussed by @evancz above.

This is a good demonstration of the problem I describe above. If you have triggered multiple calls to `window.confirm`, how do you disambiguate the subscription messages coming back in from JS?

---

<div class="post-metadata">

**Author:** ![mthadley](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mthadley/32/406_2.png) [@mthadley](https://discourse.elm-lang.org/u/mthadley)\
**Post date:** [March 12, 2018, 7:41pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/8 "2018-03-12T19:41:10Z")

</div>

You could pass some kind of id (an `Int` or `String`) to your port, which identifies the particular confirm. Then later, when the user has confirmed or canceled, your JS code can pass back that id into your `Sub` port. From there, your Elm code should be able to identify it.

---

<div class="post-metadata">

**Author:** ![Collin](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/collin/32/509_2.png) [@Collin](https://discourse.elm-lang.org/u/Collin)\
**Post date:** [March 12, 2018, 7:43pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/9 "2018-03-12T19:43:41Z")

</div>

> [@xtian](#):
>
> but that felt like a lot of complex harness for a problem that could be safely solved with three lines of native code.

I think this is the main pain point people have when being forced into ports coming from native code, however there IS still a solution going the safe route with ports albeit at the expense of terseness.

---

<div class="post-metadata">

**Author:** ![xtian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/xtian/32/1178_2.png) [@xtian](https://discourse.elm-lang.org/u/xtian)\
**Post date:** [March 12, 2018, 7:53pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/10 "2018-03-12T19:53:40Z")

</div>

> [@Collin](#):
>
> however there IS still a solution going the safe route with ports

Using ports would be more type-safe, but it would be much more complex overall and so I would say it’s actually less safe in general.

---

<div class="post-metadata">

**Author:** ![xtian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/xtian/32/1178_2.png) [@xtian](https://discourse.elm-lang.org/u/xtian)\
**Post date:** [March 12, 2018, 7:55pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/11 "2018-03-12T19:55:41Z")

</div>

> [@mthadley](#):
>
> You could pass some kind of id (an Int or String) to your port, which identifies the particular confirm.

Yeah this would work. What do you think would be the best way to generate this ID?

---

<div class="post-metadata">

**Author:** ![evancz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/evancz/32/16_2.png) [@evancz](https://discourse.elm-lang.org/u/evancz)\
**Post date:** [March 12, 2018, 8:18pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/12 "2018-03-12T20:18:34Z")

</div>

What are the different cases that can produce a confirmation popup? The structure of some applications make IDs available quite naturally, so I think we need to know more about the specifics of your case to give the best recommendation for you.

---

<div class="post-metadata">

**Author:** ![loganmac](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@loganmac](https://discourse.elm-lang.org/u/loganmac)\
**Post date:** [March 12, 2018, 9:05pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/13 "2018-03-12T21:05:02Z")

</div>

You could do something like this! (Fork of example Ellie above):

[https://ellie-app.com/bXKyKgJgBa1/1](https://ellie-app.com/bXKyKgJgBa1/1)  
(edit: simplified)

---

<div class="post-metadata">

**Author:** ![rgrempel](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rgrempel/32/93_2.png) [@rgrempel](https://discourse.elm-lang.org/u/rgrempel)\
**Post date:** [March 12, 2018, 10:01pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/14 "2018-03-12T22:01:41Z")

</div>

You could take a look at [http://package.elm-lang.org/packages/peterszerzo/elm-porter/latest](http://package.elm-lang.org/packages/peterszerzo/elm-porter/latest) … it has a nice process for associating requests and responses for ports, at the cost of a bit of setup.

---

<div class="post-metadata">

**Author:** ![xtian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/xtian/32/1178_2.png) [@xtian](https://discourse.elm-lang.org/u/xtian)\
**Post date:** [March 13, 2018, 12:01am UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/15 "2018-03-13T00:01:33Z")

</div>

Well, the IDs in our application are opaque types currently which allows us to guarantee that they will only ever be constructed by the JSON decoders or URL parsers that are exported by our data modules. We would have to compromise on that guarantee in order to use those values to disambiguate different subscription messages.

We also have an interface where users can create different shapes by placing vertices on a graph. These shapes are children of a parent resource and multiple shapes can be in an edited or unsaved (meaning they are newly created) state at once. In order to provide a deletion confirmation dialog for these shapes via ports we would need some way of determining which unsaved shape the dialog response was relevant for.

---

<div class="post-metadata">

**Author:** ![luke](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/luke/32/709_2.png) [@luke](https://discourse.elm-lang.org/u/luke)\
**Post date:** [March 13, 2018, 12:17am UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/16 "2018-03-13T00:17:12Z")

</div>

> [@xtian](#):
>
> If you have triggered multiple calls to window.confirm, how do you disambiguate the subscription messages coming back in from JS?

There’s no way to trigger more than one `window.confirm` dialog at a time since `window.confirm` is a blocking function and the only way to dismiss it is through user interaction. I’m also assuming that initiating the dialog is in response to a user interaction as well. The workflow gives you this organic guarantee that you’ll always be dealing with one dialog at a time, so you don’t really need to identify messages at all. As long as you can store which resource is up for deletion you can just wait for a message `UserDeletionResponded Bool` from your port and then proceed.

---

<div class="post-metadata">

**Author:** ![xtian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/xtian/32/1178_2.png) [@xtian](https://discourse.elm-lang.org/u/xtian)\
**Post date:** [March 14, 2018, 2:09pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/17 "2018-03-14T14:09:41Z")

</div>

> [@luke](#):
>
> There’s no way to trigger more than one window.confirm dialog at a time since window.confirm is a blocking function and the only way to dismiss it is through user interaction.

I thought message handling and ports were async, though. Seems like there could be a situation where multiple port messages from `window.confirm` were queued at once. Is this incorrect?

---

<div class="post-metadata">

**Author:** ![gampleman](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gampleman/32/43_2.png) [@gampleman](https://discourse.elm-lang.org/u/gampleman)\
**Post date:** [March 14, 2018, 3:18pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/18 "2018-03-14T15:18:34Z")

</div>

Perhaps, in theory. But an app that queues multiple `window.confirm`s at the same time seems both unlikely and pretty user-hostile. AFAIK to trigger that, you would need to have multiple requests in a single update loop iteration.

---

<div class="post-metadata">

**Author:** ![xtian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/xtian/32/1178_2.png) [@xtian](https://discourse.elm-lang.org/u/xtian)\
**Post date:** [March 14, 2018, 4:33pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/19 "2018-03-14T16:33:50Z")

</div>

Sure, it just feels like at this point we would be depending on convention and side-effects to produce correct behavior rather than having some technical guarantee that messages are being processed correctly. That’s an uncomfortable place to be, especially when debugging.

---

<div class="post-metadata">

**Author:** ![luke](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/luke/32/709_2.png) [@luke](https://discourse.elm-lang.org/u/luke)\
**Post date:** [March 14, 2018, 5:37pm UTC](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844/20 "2018-03-14T17:37:53Z")

</div>

In any case, native code will not be available in 0.19 and a binding to `window.confirm` will not be included in any packages, so using a port is the path forward. You can:

- rely on the behavior of `window.confirm` and your program’s UX to ensure that a dialog can only be triggered after the previous one is resolved. This is the choice that I would make personally, but I don’t work on your team and so I don’t know all of your constraints.
- use something like a [Lamport timestamp](https://en.wikipedia.org/wiki/Lamport_timestamps) as an ID for your port messages such that you can track which message ID is the latest and discard messages that don’t match.
- identify your `window.confirm`-related port messages using the ID of the related resource. If the ID type is opaque, you might include something like the following in the module that defines it:

```auto
type alias PortId = String

toPortId : Id -> PortId
toPortId (Id value) = "port:" ++ value

```

[Next page](https://discourse.elm-lang.org/t/window-confirm-without-native-code/844.md?page=2)
