First, your decoder function is a bit off. There is no intermediate โattributesโ object, so you can change it to this:
decoder : Decoder Job decoder = Decode.object3 Job ("task" := Decode.string) ("who" := Decode.string) ("place" := Decode.string)
You are correct that you will need the elm-http package. Using this, you can create an Http.get task that maps the result to action.
As a basic example, make a button that pulls a list of tasks from a URL. We need the GetJobs action to start the HTTP request and the ShowJobs action, which will be triggered ShowJobs request ShowJobs .
Assuming our type of action is as follows:
type Action = NoOp | GetJobs | ShowJobs (Maybe Jobs)
Then we can create a GetJobs function that creates a task that can be started. For this simple example, we can use Task.toMaybe to suppress any HTTP or JSON decoding errors.
getJobs : Effects Action getJobs = Http.get decoderColl jobsUrl |> Task.toMaybe |> Task.map ShowJobs |> Effects.task
To glue everything together, we will use StartApp , as it allows us to use tasks and effects. Here is a working example that you can create locally, assuming jobs.json exists in the same directory.
import Http import StartApp import Effects exposing (Effects,Never) import Task import Html exposing (..) import Html.Events exposing (..) import Json.Decode as Decode exposing (Decoder, (:=)) jobsUrl = "./jobs.json" -- StartApp plumbing app = StartApp.start { init = init, view = view, update = update, inputs = [] } main = app.html port tasks : Signal (Task.Task Never ()) port tasks = app.tasks type Action = NoOp | GetJobs | ShowJobs (Maybe Jobs) type alias Model = { jobs : Maybe Jobs } init = ({ jobs = Nothing }, Effects.none) update action model = case action of NoOp -> (model, Effects.none) GetJobs -> ({ model | jobs = Nothing }, getJobs) ShowJobs maybeJobs -> ({ model | jobs = maybeJobs }, Effects.none) view address model = div [] [ button [ onClick address GetJobs ] [ text "Click to get jobs!" ] , viewJobs model.jobs ] viewJobs maybeJobs = let viewJob job = li [] [ text ("Task: " ++ job.task ++ "; Who: " ++ job.who ++ "; Place: " ++ job.place) ] in case maybeJobs of Nothing -> div [] [ text "No jobs to display. Try clicking the button" ] Just jobs -> ul [] (List.map viewJob jobs) -- This is the key to map the result of the HTTP GET to an Action -- Note: Task.toMaybe swallows any HTTP or JSON decoding errors getJobs : Effects Action getJobs = Http.get decoderColl jobsUrl |> Task.toMaybe |> Task.map ShowJobs |> Effects.task -- An alternative to Task.toMaybe which dumps error information to the console log toMaybeWithLogging : Task.Task xa -> Task.Task y (Maybe a) toMaybeWithLogging task = Task.map Just task `Task.onError` (\msg -> Debug.log (toString msg) (Task.succeed Nothing)) -- The Job type aliases from the question type alias Job = { task : String , who : String , place: String } type alias Jobs = List Job -- The updated Job decoder decoder : Decoder Job decoder = Decode.object3 Job ("task" := Decode.string) ("who" := Decode.string) ("place" := Decode.string) decoderColl : Decoder Jobs decoderColl = Decode.object1 identity ("jobs" := Decode.list decoder)