# Producing side effects directly from view functions?

**URL:** <https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323>\
**Category:** Learn\
**Created:** [December 24, 2017, 4:10pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323 "2017-12-24T16:10:50Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![charliek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/charliek/32/3865_2.png) [@charliek](https://discourse.elm-lang.org/u/charliek)\
**Post date:** [December 24, 2017, 4:10pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/1 "2017-12-24T16:10:50Z")

</div>

I’d like to clarify my understanding on why views cannot produce side-effects directly.

[Here is an example](https://ellie-app.com/3B4rMsWQma1/0) where I have a simple view with a button. When the user clicks the button I’d like to produce a random value (a side-effect), but in order to do so I need to produce a `Cmd Msg` which can only be done from the `update` function. So another distinct `Msg` is needed to tell the update function to produce the Cmd.

I understand why this is strictly from a function annotation perspective. You need a `Cmd` to produce a side-effect. Randomness (with `Random.generate`) is a side-effect and the view function’s annotation doesn’t work with Cmds.

I can’t say I understand it from a TEA perspective yet and that I’m missing something obvious. Shouldn’t event handlers in the view be able to produce side-effects directly?

---

<div class="post-metadata">

**Author:** ![ilias](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ilias/32/6_2.png) [@ilias](https://discourse.elm-lang.org/u/ilias)\
**Post date:** [December 25, 2017, 9:38am UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/2 "2017-12-25T09:38:43Z")

</div>

So, as it stands, the _only_ way to execute side-effects if with a `Cmd msg`. This means I can look at any piece of code and get a sense of where side-effects are happening very easily: just look for `Cmd msg` and I’m good to go.

While I can’t think of a technical reason why `Html msg` wouldn’t be able to produce side-effects in response to events, I _do_ feel like it would be an extra complication for the user. Where are side-effects produced? Well, look for `Cmd msg` and also read all the `view` code because some event somewhere may produce a side-effect, somewhere.

I fear it would also encourage moving your business logic into your views. I like that the current model is “it’s just a pure function that describes how to render your app given the current state”. `update`, then, is the single place where you decide what to do next, based on the current state (the model) and information on what just happened (the message).

That said, generating randomness doesn’t require side-effects in Elm, as long as you keep track of the seed. So creating a random int when you click a button is already possible: [https://ellie-app.com/bGgCF2p6ka1/0](https://ellie-app.com/bGgCF2p6ka1/0)

---

<div class="post-metadata">

**Author:** ![eeue56](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eeue56/32/7_2.png) [@eeue56](https://discourse.elm-lang.org/u/eeue56)\
**Post date:** [December 25, 2017, 7:31pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/3 "2017-12-25T19:31:29Z")

</div>

So while it’s true that the majority of apps and recommendations focus on using a message to tell your app what to do next, be it update the model or the command itself, it is possible to create an exectuor constructor for your `Msg` that will simply just run the commands you give it. For example:

```auto
type Msg = Command (Cmd Msg)

update : Msg -> Model -> (Model, Cmd Msg)
update msg model = 

   case msg of 
      Command cmd -> (model, cmd)

```

You can see how this would look as a working example here: [https://ellie-app.com/embed/nBXyMcVVFa1/0](https://ellie-app.com/embed/nBXyMcVVFa1/0). I’ve seen at least 2 people use this in production, the argument being that seeing directly which side-effects get triggered by which views allow the reader to better identify what happens. One of the major downside of this approach is that your view code suddenly contains code you’d expect to only find in the update function. I’d recommend keeping the centralized effects approach, instead.

---

<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:** [December 25, 2017, 9:59pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/4 "2017-12-25T21:59:03Z")

</div>

> [@charliek](#):
>
> Shouldn’t event handlers in the view be able to produce side-effects directly?

One concrete practical reason they shouldn’t is `requestAnimationFrame` batching.

Right now, if I subscribe to `mousemove`, I’ll get flooded with events when the user moves the mouse. Each time an event comes in, `update` runs, potentially changes `Model`, and potentially runs more effects.

However, regardless of how quickly events are coming in, the Elm Runtime still only calls `view` once per animation frame - with whatever the current `Model` happens to be at that moment. It can do this optimization safely because `view` only returns `Html` and performs no side effects. Since `view` cannot possibly do anything other than describe how the page ought to look, it’s always safe to skip running it except when it’s potentially time to change how the page looks.

Now suppose `view` had the type `Model -> ( Html Msg, Cmd Msg )` instead.

In this world,it’s no longer safe to skip calling `view` under any circumstances. If we get flooded with events, we have to call both `update` and `view` on every single event, no matter what. After all, what if `view` was going to produce an effect on the 14,203rd invocation? There’s no way to know without running it every single time.

That’s is a hefty performance price to pay for being able to have both `view` and `update` describe effects directly. 😅

I’d say there are other design principle reasons to keep them separated, but this is one practical reason. 🙂

---

<div class="post-metadata">

**Author:** ![charliek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/charliek/32/3865_2.png) [@charliek](https://discourse.elm-lang.org/u/charliek)\
**Post date:** [December 26, 2017, 12:53am UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/5 "2017-12-26T00:53:59Z")

</div>

I should clarify my phrasing.

My title was poorly worded. I don’t mean to say that invoking a view function should produce a side effect. That’d be just as strange as invoking a view function that returns a Msg.

Rather, I’m wondering about something like `view : Model -> Html (Cmd Msg)`.

Perhaps not exactly that, but something like that demonstrates what I’m thinking. It’s a view function that doesn’t return side effects but it is a function that _returns Html that is capable of producing side effects_.

[I updated the example](https://ellie-app.com/embed/3B4rMsWQma1/1) to make explicit what I’m talking about. It doesn’t compile and there are nits to pick, but the changes to `update` and `view` demonstrate my question. It’s similar to what @eeue56 suggested but with less boilerplate.

---

<div class="post-metadata">

**Author:** ![charliek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/charliek/32/3865_2.png) [@charliek](https://discourse.elm-lang.org/u/charliek)\
**Post date:** [December 26, 2017, 12:59am UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/6 "2017-12-26T00:59:09Z")

</div>

Relevant code to make it easier to find…

```
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        RandomResult suit ->
            Just suit ! []

-- ...

view : Model -> ???
view model =
    div
        []
        [ button
            [onClick clickCmd]
            [text "Random Suit"]
        , suitView model
        ]

clickCmd : Cmd Msg
clickCmd =
    Random.generate RandomResult suitGenerator
```

---

<div class="post-metadata">

**Author:** ![eeue56](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eeue56/32/7_2.png) [@eeue56](https://discourse.elm-lang.org/u/eeue56)\
**Post date:** [December 26, 2017, 1:14am UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/7 "2017-12-26T01:14:28Z")

</div>

You can do `view : Model -> Html (msg, Cmd msg)`, but that uses more boilerplate. Here’s a question for you: what about the cases where you need to update the model during the firing of a command? For example, if you have a form and the command in question is to store that data in a server and wait for the response. How would you want that to look?

---

<div class="post-metadata">

**Author:** ![charliek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/charliek/32/3865_2.png) [@charliek](https://discourse.elm-lang.org/u/charliek)\
**Post date:** [December 26, 2017, 1:22am UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/8 "2017-12-26T01:22:04Z")

</div>

> [@eeue56](#):
>
> what about the cases where you need to update the model during the firing of a command?

Note that I’m not suggesting that `update`’s annotation should change. I’m not really suggesting anything. I’m only trying to better my understanding on why all side effects must ultimately go through `update` even though there are some side effects that come from Html event handlers and don’t make any changes to the model.

---

<div class="post-metadata">

**Author:** ![brian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/brian/32/2180_2.png) [@brian](https://discourse.elm-lang.org/u/brian)\
**Post date:** [December 26, 2017, 1:26am UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/9 "2017-12-26T01:26:41Z")

</div>

Imagine you have the following flows:

| `Msg` | `update` filter | emitted `Cmd Msg` |
| --- | --- | --- |
| Click Submit, Keyboard Cmd+Enter | is the submitted data valid? | `(model, postNewFormData)` |
| Click X, Keyboard Esc | is the modal open? | `({m | modalState = Closed}, Cmd.none)` |

These are some pretty common situations! And in these, if you have your `Cmd Msg` emitted from `view`…

1. you have to handle validation and `postNewFormData` in every event handler instead of once in `update`.
2. you can’t update the model/modal without changing to `view : Model -> Html (Model, Cmd Msg)`.

I think that #2 illustrates why we don’t do this best: because it is not the view’s responsibility! Once it’s both `update` and `view`, it mixes event handling and presentation. These are separate domains, why shouldn’t they be separate functions?

I’ve been told that certain cljs frameworks have done this, and that it has been their fatal flaw. Once you couple these two domains, you start expecting the data to be shaped the same as your view. This makes refactoring a whole lot harder than it would have to be!

---

<div class="post-metadata">

**Author:** ![ilias](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ilias/32/6_2.png) [@ilias](https://discourse.elm-lang.org/u/ilias)\
**Post date:** [December 26, 2017, 11:53am UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/10 "2017-12-26T11:53:52Z")

</div>

I interpreted the question as _what if `Html msg` were more like `Cmd msg`_.

In other words, _what if there were a function like this: `on : String -> Decoder (Cmd msg) -> Html.Attribute msg`_.

A practical issue with that approach is that commands are asynchronous. If a command (say, an HTTP request) takes a while, what should happen to events that arrive in the meantime? If we let them through, that means the order of actions by the user doesn’t correspond to the order in which messages in `update` arrive, which could potentially be very confusing.

My previous comments about needing to actually read the view code to figure out where side-effects happen still stand - assuming the signature wouldn’t change, I’d presumably end up with a mix of “pure” events and “side-effectful” events.

So, my opinion: `Html msg` synchronously bubbles events to `update` because it’s the least confusing thing to do and there are no obvious advantages to doing it differently.

---

<div class="post-metadata">

**Author:** ![Viir](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/viir/32/4103_2.png) [@Viir](https://discourse.elm-lang.org/u/Viir)\
**Post date:** [December 26, 2017, 4:31pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/11 "2017-12-26T16:31:53Z")

</div>

> [@ilias](#):
>
> A practical issue with that approach is that commands are asynchronous. If a command (say, an HTTP request) takes a while, what should happen to events that arrive in the meantime? If we let them through, that means the order of actions by the user doesn’t correspond to the order in which messages in update arrive, which could potentially be very confusing.

This helped me best to understand the problem with the example use case given:

> _When the user clicks the button I’d like to produce a random value (a side-effect)_.

Looking at this use case, it was easy for me to forget that API-wise, `Random.generate` is just as asynchronous (and can take just as long) as communication with a remote system.

When I think of how long it could take to get a result, it makes sense. I would not want to leave the user wondering, has my request registered by the system? I would want to update the UI in the meantime to inform the user that the system is working on it.

---

<div class="post-metadata">

**Author:** ![charliek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/charliek/32/3865_2.png) [@charliek](https://discourse.elm-lang.org/u/charliek)\
**Post date:** [December 26, 2017, 4:49pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/12 "2017-12-26T16:49:01Z")

</div>

@brian I definitely agree that if the model needs to be updated at the same time that a `Cmd Msg` is produced then the current architecture supports that well.

These responses are helping me understand what my question really is and it’s more of an observation. If in response to an Html event a side-effect needs to be produced _and the model does not need to be updated_, then the current architecture requires a bit more boilerplate.

> [@ilias](#):
>
> In other words, what if there were a function like this: on : String -\> Decoder (Cmd msg) -\> Html.Attribute msg.

@ilias This is spot on to what I was thinking. Html events very often produce side-effects and the model may or may not need to be updated when that side effect is produced.

I’m not sure I understand why Cmds being asynchronous is an issue. Msgs are asynchronous too.

While thinking about this something else occurred to me. Sometimes a Cmd needs to know about the current model to know what side effect it should produce. That would require a change to `on` and others.

`on : String -> (model -> Decoder (Cmd msg)) -> Html.Attribute msg`

I’m still wondering if there’s a more elegant solution at the level of the Elm architecture. Something I’ll ponder on for a while…

---

<div class="post-metadata">

**Author:** ![ilias](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ilias/32/6_2.png) [@ilias](https://discourse.elm-lang.org/u/ilias)\
**Post date:** [December 26, 2017, 5:16pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/13 "2017-12-26T17:16:17Z")

</div>

> [@charliek](#):
>
> I’m not sure I understand why Cmds being asynchronous is an issue. Msgs are asynchronous too.

Messages produced by HTML events arrive in the exact order as the events happened. Commands have no ordering guarantees, but html-events do. I’m not sure how big of an issue this would be _in practice_.

I’ve been trying to think of cases where the model wouldn’t be updated (and hence, this discussion makes sense). It seems that for most actions, you want to inform the user somehow (e.g. disable a form while it’s submitting, show a “loading” state while loading data, …). The most notable exception that comes to mind that makes sense as a direct result from user-interaction is navigation. For hash-navigation, we can and do already use a direct side-effect: the URL changes, which triggers the subscription, which informs `update`.

> [@charliek](#):
>
> Html events very often produce side-effects and the model may or may not need to be updated when that side effect is produced.

I think that’s the crux of my argument: whether an HTML event should change the model, trigger a side-effect to happen or both isn’t for my `view` to decide. The mental model that events product messages that inform you that something happened so you can respond to it based on the current state is a very simple one.

In my experience, having a central “hub” where messages are mapped to actions (producing new state and/or producing commands for the runtime) is a great for maintainability: I can read `update` and get a sense of what’s going on.

> [@charliek](#):
>
> Sometimes a Cmd needs to know about the current model to know what side effect it should produce. That would require a change to on and others.
> 
> ```auto
> on : String -> (model -> Decoder (Cmd msg)) -> Html.Attribute msg
> 
> ```

I’m not sure why that would be the case - a `view` already has the `model` (or the relevant part for that view), so couldn’t it apply that `model -> Decoder (Cmd msg)` function to the `model` and pass the `Decoder (Cmd msg)` to this imaginary `on`?

---

<div class="post-metadata">

**Author:** ![charliek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/charliek/32/3865_2.png) [@charliek](https://discourse.elm-lang.org/u/charliek)\
**Post date:** [December 26, 2017, 5:31pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/14 "2017-12-26T17:31:44Z")

</div>

> [@ilias](#):
>
> I’ve been trying to think of cases where the model wouldn’t be updated (and hence, this discussion makes sense).

Two side effects without model changes that come to mind is randomness using `Random.generate` or using a port “synchronously”. The original post has an example for randomness. An example using a port might be clicking a button to plot a point on a third-party mapping library like [CesiumJS](https://cesiumjs.org/) or [Leaflet](http://leafletjs.com/). In either case you wouldn’t want to update the model until that side-effect was performed successfully.

> [@ilias](#):
>
> I’m not sure why that would be the case - a view already has the model (or the relevant part for that view), so couldn’t it apply that model -\> Decoder (Cmd msg) function to the model and pass the Decoder (Cmd msg) to this imaginary on?

As @rtfeldman pointed out the view is only called once per animation frame. Additionally, that might get hokey when used with `Html.Lazy`. The point is the view isn’t necessarily guaranteed to have the latest model in my understanding.

> [@ilias](#):
>
> In my experience, having a central “hub” where messages are mapped to actions (producing new state and/or producing commands for the runtime) is a great for maintainability

Agreed. That’s why I’m wondering if there’s a more elegant solution (rethinking how side effects work in TEA rather than duct taping a modification to it).

---

<div class="post-metadata">

**Author:** ![brian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/brian/32/2180_2.png) [@brian](https://discourse.elm-lang.org/u/brian)\
**Post date:** [December 26, 2017, 5:54pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/15 "2017-12-26T17:54:53Z")

</div>

> [@ilias](#):
>
> In my experience, having a central “hub” where messages are mapped to actions (producing new state and/or producing commands for the runtime) is a great for maintainability: I can read update and get a sense of what’s going on.

This is crucial! If side effects are produced in the view, you no longer know where all the side effects live. I think that’s the core answer to your “why?”, @charliek. This is a case where the benefits of removing “boilerplate” are not worth the drawbacks.

Also, in my experience it is good to separate your system’s events from the user’s intent. So this:

```elm
snippet : Html Msg
snippet =
    button [onClick ShuffleCards] [text "Shuffle!"]

```

is way better than this:

```elm
snippet : Model -> Html Msg
snippet model =
    button [onClick (SetOrder model.nextCardOrder)] [text "Shuffle!"]

```

In short, I guess I don’t get your motivation! Is there some concrete thing you’re trying to do which is really painful because of the way `view` is set up now?

---

<div class="post-metadata">

**Author:** ![charliek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/charliek/32/3865_2.png) [@charliek](https://discourse.elm-lang.org/u/charliek)\
**Post date:** [December 26, 2017, 6:43pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/16 "2017-12-26T18:43:45Z")

</div>

> [@brian](#):
>
> Is there some concrete thing you’re trying to do which is really painful because of the way view is set up now?

Nope! I started with [this example](https://ellie-app.com/embed/3B4rMsWQma1/0) and wasn’t clear on why I needed to produce a Msg to produce a side effect which produces a final Msg. Only trying to better understand why that is necessary.

---

<div class="post-metadata">

**Author:** ![cjduncana](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/cjduncana/32/192_2.png) [@cjduncana](https://discourse.elm-lang.org/u/cjduncana)\
**Post date:** [December 26, 2017, 10:10pm UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/17 "2017-12-26T22:10:46Z")

</div>

Here, I have a version of your Elm app that doesn’t produce any side-effects: [https://ellie-app.com/qr6W23TBka1/1](https://ellie-app.com/qr6W23TBka1/1)

The changes that I made include:

1. Add an integer flag to initialize the model with a random seed
2. Add a random integer generator in the JS side (the only side effect is outside the Elm app)
3. Use `Random.step` to produce a random result and the next seed in a completely pure fashion

If you notice the update function always returns a `Cmd.none` with the updated model. If it wasn’t for the flags, this could be converted into a `Html.beginnerProgram`. Hope this helps you out.

---

<div class="post-metadata">

**Author:** ![turboMaCk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/turbomack/32/355_2.png) [@turboMaCk](https://discourse.elm-lang.org/u/turboMaCk)\
**Post date:** [May 17, 2021, 7:44am UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/18 "2021-05-17T07:44:09Z")

</div>

> [@charliek](#):
>
> Shouldn’t event handlers in the view be able to produce side-effects directly?

No. You don’t want to think about when and how often view is called. This is why we have `update` function and `Msg` type. It helps to keep even handles in view lazy so there is no construction of extra values during every render to vdom.

In lazy language like haskell it might make sense to abandon `update` and `Msg` comnpletely and do implement these things in view. There is still a concern of interleaving of course but update function doesn’t solve that one either. [Shpadoinkle](https://hackage.haskell.org/package/Shpadoinkle) is GHCjs framework that explores “update less” / “effectful view” pattern. In strict language you can do this as well but for sure there is some pressure on programmer to make sure stuff doesn’t evaluate all the time.

---

<div class="post-metadata">

**Author:** ![rupert](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rupert/32/1775_2.png) [@rupert](https://discourse.elm-lang.org/u/rupert)\
**Post date:** [May 17, 2021, 11:11am UTC](https://discourse.elm-lang.org/t/producing-side-effects-directly-from-view-functions/323/19 "2021-05-17T11:11:08Z")

</div>

> [@charliek](#):
>
> Shouldn’t event handlers in the view be able to produce side-effects directly?

I think the use case is not the one the OP had in mind, but be aware that it is possible to run the `update` function immediately in response to an event on the view - which sounds a lot like the view being able to side-effect directly, depending on what we understand by that statement.

See notes 2 and 3 here for an explanation:

[https://package.elm-lang.org/packages/elm/virtual-dom/latest/VirtualDom#Handler](https://package.elm-lang.org/packages/elm/virtual-dom/latest/VirtualDom#Handler)
