Let's take a step back, here.
Conceptually, the `init` function is meant to say how to jumpstart your
application. So what it should do, is provide the initial state of your
model, and - optionally - telling the runtime to start executing some
asynchronous task right away (a good example would be fetching some remote
resource), as a Cmd.
When the runtime receives such a Cmd, it will do what your commanded it to
do, and then call your `update` function with the current state of the
model and the Msg that resulted from your Cmd.
Using `Task.perform` with a "no op" task to "trick" the runtime into
calling your update feels wrong, as you say yourself. I'd argue that it's
definitely abusing the the runtime, too.
So, let's have a look at what you are trying to accomplish: you want to
execute a function on your model, before declaring it "final". You could do
that by calling `update` with the appropriate Msg from your init function,
*or* you could split off that branch into a proper function that transforms
your model.
What you'd end up with, then, is something like this:
```
init : (Model, Cmd msg)
init =
( initialModel |> transformIt, Cmd.none)
```
Your update function would call that exact same function - which means you
could think of the update function like a sort of "translation" from
messages to function calls that transform your model, rather than the one
central place to bundle all your logic.
Hope this helps :)
Kr,
Ilias
Op woensdag 8 maart 2017 22:50:00 UTC+1 schreef Duane Johnson:
>
> Preface: while I've been using Elm for a while, I've only just begun using
> messages and commands, so it's ok to treat me like a newbie here. This is a
> capture of my experience of Elm while trying to figure out how to send an
> initial message.
>
>
> I find the `Cmd` type a little confusing, especially in the init function.
> Conceptually, I want to "kick off" an initial fetch of data from client to
> server, and it would make intuitive sense if I were permitted to do this:
>
> ```
> init : (Model, Msg)
> init =
> { initialModel, FetchStatus 0 }
> ```
>
> But instead, the type of `init` is required to be this:
>
> ```
> init : (Model, Cmd Msg)
> init =
> { initialModel, ... }
> ```
>
> When I get to this point, I need to look up the documentation on Cmd.
> Having read the guide several months ago, I have a vague impression that I
> may need to "perform" something to get my message into a Cmd type. I look
> at the `Platform.Cmd` documentation, and I see there's a `Cmd` type which
> looks like a constructor. So I try this:
>
> ```
> init : (Model, Cmd Msg)
> init =
> { initialModel, Cmd (FetchStatus 0) }
> ```
>
> But I get an error: "Cannot find variable `Cmd`". Having some experience
> with Elm, I believe this may mean although Cmd is a type, its constructor
> is not exposed.
>
> At this point, the `map` function looks a little promising, because it
> takes some things that are not Cmd and produces `Cmd msg`, i.e. precisely
> the type I'm looking for. However, it's not clear to me what the first
> parameter to map is (a function that takes `a` and produces `msg`?) There's
> no documentation on this `map` function.
>
> Then I peruse the docs some more ("maybe this is so common a thing that it
> belongs in Basics? or maybe I missed something in Platform, since Cmd is a
> submodule of Platform?") and arrive at the Task documentation, where I see
> the "perform" signature:
>
> perform
> <http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Task#perform> :
> (a -> msg) -> Task
> <http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Task#Task> Never
> <http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Basics#Never> a
> -> Cmd
> <http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Platform-Cmd#Cmd>
> msg
>
> This looks promising as well, because it takes some things and produces a
> `Cmd msg`. But the example in the documentation shows how to use `perform`
> with `Time.now` which further confuses things because I just want to pass a
> Time value to my FetchStatus, like it was meant to receive (not necessarily
> a "now" value). If I try this:
>
> ```
> init : ( Model, Cmd Msg )
> init =
> ( initialModel, Task.perform FetchStatus 0 )
> ```
>
> I get
>
> ```
> Function `perform` is expecting the 2nd argument to be:
> Task.Task Never Time
> ```
>
> So finally I realize that I need to pass a "succeed" task to my `perform`
> call so I can create a `Cmd msg` of the type I need:
>
> ```
> init : ( Model, Cmd Msg )
> init =
> ( initialModel, Task.perform FetchStatus (Task.succeed 0) )
> ```
>
> Subjectively, this all feels more convoluted than it needs to be. At a
> basic level, I want to communicate an initial model and an initial "kick
> off" message. It's confusing that Task types are involved in constructing
> Cmd types. This makes finding the right documentation difficult. In
> addition, it isn't clear why a Cmd is needed at all--why not a Msg, or a
> List Msg? Conceptually, this would be a lower barrier to entry.
>
> This is just a running journal of my experience trying to do a basic Elm
> task (no pun intended). I hope it helps make the Elm experience better in
> some way for others.
>
> Best,
> Duane
>
--
You received this message because you are subscribed to the Google Groups "Elm
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.