Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elm Http Request on Init

Tags:

elm

I'm pretty new to Elm, but slowly getting familiar with it. I'm doing some simple Http Requests, which are successful in every aspect (I get the data to display, etc.)

For the moment I can only get my fetchData to trigger onClick, I would like to initialize this on init, but I'm having trouble wrapping my head around this.

....here is my fetchData function:

fetchData : Cmd Msg
fetchData =
  Http.get repoInfoListDecoder "http://example/api"
    |> Task.mapError toString
    |> Task.perform ErrorOccurred DataFetched

Which is currently trigger in the view by a onClick event:

.....
, button [ onClick FetchData ] [ text "Load Data" ]
.....

I want to avoid requesting the data by a button, instead I want the data to load when the app is initialized. Here is my init:

init =
  let
    model =
      { message = "Welcome", repos = [] }
  in
    model ! []

And my update (kind of stripped...for example's sakes):

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    NoOp ->
      model ! []
    ...........
    FetchData ->
      { model | message="hi" } ! [fetchData]
    ...........
    DataFetched repos ->
      { model | repos = repos, message = "The data has been fetched!" } ! []

Does this makes sense? I'm just having difficulty initializing fetchData when the app loads, so I can display my data without having to hit a button to fetch it.

Thanks in advance!

like image 439
mmmaceo Avatar asked Oct 10 '16 21:10

mmmaceo


3 Answers

When you use Html.program, your init function returns the initial data for your Model and Command to be executed.

Commands are side-effects, like HTTP requests.

Try changing init so it runs a Command right away:

init: (Model, Cmd Msg)
init =
  let
    model =
      { message = "Welcome", repos = [] }
  in
    model ! [ fetchData ]
like image 65
halfzebra Avatar answered Nov 20 '22 23:11

halfzebra


Here is the type signature of Html.App.program. init accepts Cmd, you simply give your Cmd here.

program
    :  { init : (model, Cmd msg), update : msg -> model -> (model, Cmd msg), subscriptions : model -> Sub msg, view : model -> Html msg }
    -> Program Never
like image 1
Tosh Avatar answered Nov 20 '22 22:11

Tosh


Another way is to use Task, which hasn't been mentioned yet. You could try something like

initWithFlags : Flags -> ( Model, Cmd Msg)
initWithFlags flags =
    ( { user = flags.user }, (Task.perform fetchData) )
like image 1
Joseph Cho Avatar answered Nov 20 '22 23:11

Joseph Cho