# \`Task.perform\`/\`Time.now\` called once but firing twice

**URL:** <https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082>\
**Category:** Learn\
**Created:** [April 16, 2023, 9:44pm UTC](https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082 "2023-04-16T21:44:02Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![neurodynamic](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/neurodynamic/32/984_2.png) [@neurodynamic](https://discourse.elm-lang.org/u/neurodynamic)\
**Post date:** [April 16, 2023, 9:44pm UTC](https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082/1 "2023-04-16T21:44:03Z")

</div>

I’m trying to figure out a really weird bug. In some cases when I run `Time.now`, it seems like it consistently gets triggered twice and I can’t figure out any reason why.

Relevant code (I have a `Timestamp` data type in my app), so this is the context for the `now` function (with some Debug.log statements included):

```elm
module Utils.Types.Timestamp exposing (Timestamp(..), now)

type Timestamp
    = Timestamp Int

now : (Timestamp -> msg) -> Cmd msg
now msg =
    let
        _ =
            Debug.log "Timestamp.now msg" msg
    in
    Task.perform
        (\posix ->
            let
                _ =
                    Debug.log "perform msg" msg
            in
            msg (fromTime posix)
        )
        Time.now

fromTime : Posix -> Timestamp
fromTime time =
    time
        |> Time.posixToMillis
        |> Timestamp

```

When some parts of my code call this function, it prints what you would expect:

```auto
Timestamp.now msg: <function>
perform msg: <function>

```

But in others, this happens:

```auto
Timestamp.now msg: <function>
perform msg: <function>
perform msg: <function>

```

`Timestamp.now` is only being called once, but somehow `Task.perform` is getting triggered twice (if I print the resulting timestamp, I get two veeeery slightly different timestamps, like `1681681068968` vs `1681681068971`). Is it possible there’s a bug in the `Time.now` or `Task.perform` implementations or something that causes this to sometimes trigger twice? Or is there another possibility I’m missing? I’m completely bewildered.

---

<div class="post-metadata">

**Author:** ![dta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dta/32/1917_2.png) [@dta](https://discourse.elm-lang.org/u/dta)\
**Post date:** [April 17, 2023, 2:14am UTC](https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082/2 "2023-04-17T02:14:03Z")

</div>

In Elm, tasks are executed not when `Task.perform` is called, but when the resulting command is returned from `update` (or `init`). Is it possible that you’re returning the same command more than once?

---

<div class="post-metadata">

**Author:** ![neurodynamic](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/neurodynamic/32/984_2.png) [@neurodynamic](https://discourse.elm-lang.org/u/neurodynamic)\
**Post date:** [April 17, 2023, 5:33pm UTC](https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082/3 "2023-04-17T17:33:27Z")

</div>

I can’t figure out how it would be, but will try and see if there’s a way it could be. That said, even in that case, wouldn’t we still expect `Timestamp.now msg: <function>` to be output twice as well?

---

<div class="post-metadata">

**Author:** ![dta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dta/32/1917_2.png) [@dta](https://discourse.elm-lang.org/u/dta)\
**Post date:** [April 17, 2023, 6:58pm UTC](https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082/4 "2023-04-17T18:58:53Z")

</div>

No, the “Timestamp.now msg” would be printed when `now` is called and the command is created.

---

<div class="post-metadata">

**Author:** ![neurodynamic](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/neurodynamic/32/984_2.png) [@neurodynamic](https://discourse.elm-lang.org/u/neurodynamic)\
**Post date:** [April 21, 2023, 8:11pm UTC](https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082/5 "2023-04-21T20:11:36Z")

</div>

So I think you turned out to be spot-on on this. I’ve been dealing with a lot of very strange both duplicating and disappearing `Cmd` bugs recently and it took me a while to figure out where they were coming from but I think I’ve finally figured it out. It was a _weird_ ride.

---

<div class="post-metadata">

**Author:** ![Carsten\_Konig](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/carsten_konig/32/4063_2.png) [@Carsten\_Konig](https://discourse.elm-lang.org/u/Carsten_Konig)\
**Post date:** [April 22, 2023, 8:38am UTC](https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082/6 "2023-04-22T08:38:10Z")

</div>

what was the root cause in the end? Maybe we/others can learn from your findings.

---

<div class="post-metadata">

**Author:** ![neurodynamic](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/neurodynamic/32/984_2.png) [@neurodynamic](https://discourse.elm-lang.org/u/neurodynamic)\
**Post date:** [April 22, 2023, 11:03am UTC](https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082/7 "2023-04-22T11:03:41Z")

</div>

So since I have some `update` function nesting in my app, I have some kind of weird update functions. Instead of returning a `(Model, Cmd msg)` tuple, they return what I’ve called a `BubbleUp` record that looks like this

```elm
type alias BubbleUp model msg instructions =
    { model : model
    , cmd : Cmd msg
    , bubble : BubbleUpData instructions
    }

type alias BubbleUpData instructions =
    { error : Maybe Report
    , modal : Maybe ModalType
    , instructions : Maybe instructions
    }

```

The `BubbleUpData` part gets passed from nested update functions up the the top update function so that, for example, all of the error reporting for the application happens in the same place at the very top.

And I wrote an `andThen` function for chaining BubbleUp record operations when I might need to apply several functions that may add changes to both the model and the Cmds. It currently looks like this:

```auto
andThen :
    (BubbleUp model msg instructions -> BubbleUp model msg instructions)
    -> BubbleUp model msg instructions
    -> BubbleUp model msg instructions
andThen bubbleUpFunc bubbleUp =
    let
        nextBubbleUp =
            bubbleUp
                |> withCmd Cmd.none
                |> bubbleUpFunc
    in
    { model = nextBubbleUp.model
    , cmd = Cmd.batch [bubbleUp.cmd, nextBubbleUp.cmd]
    , bubble =
        { error =
            bubbleUp.bubble.error
                |> Maybe.or nextBubbleUp.bubble.error
        , modal =
            bubbleUp.bubble.modal
                |> Maybe.or nextBubbleUp.bubble.modal
        , instructions =
            bubbleUp.bubble.instructions
                |> Maybe.or nextBubbleUp.bubble.instructions
        }
    }

```

So I might have an update function branch that’s like:

```elm
CloseHelpMenu ->
    model
    |> Model.closeHelpMenu
    |> BubbleUp.fromModel
    |> BubbleUp.withCmd (setFocus model.previouslyFocusedElement)
    |> BubbleUp.andThen doSomeOtherStuff

```

The tricky part is in how Cmds are handled. If the `andThen` function doesn’t have that `|> withCmd Cmd.none` line, then if `doSomeOtherStuff` _doesn’t_ set a command of its own, that `Cmd.batch [bubbleUp.cmd, nextBubbleUp.cmd]` line will batch the `setFocus model.previouslyFocusedElement` Cmd _with another copy of itself_, doubling it up.

That was the main thing I had to figure out. The similar _disappearing_ Cmds issue I had was happening because I was using `andThen` in some places and not others, so the places I was using it, everything was working fine, but the places I wasn’t, if a `BubbleUp` record got passed through a chain of functions and more than one of those functions called `withCmd`, only the very last Cmd that was set would actually get triggered, because without the batching in the `andThen` function, each call to `withCmd` just replaces whatever command was previously set.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [May 2, 2023, 11:04am UTC](https://discourse.elm-lang.org/t/task-perform-time-now-called-once-but-firing-twice/9082/8 "2023-05-02T11:04:33Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
