Skip to content

Instantly share code, notes, and snippets.

@cobalamin
Last active August 24, 2016 14:34
Show Gist options
  • Save cobalamin/478317257ce48c2dd22cf8fe0abf3792 to your computer and use it in GitHub Desktop.
Save cobalamin/478317257ce48c2dd22cf8fe0abf3792 to your computer and use it in GitHub Desktop.
module FetchParallel2 exposing (..)
import Html exposing (Html, div, text, ul, li)
import Html.App exposing (program)
import Task
import Http
import Json.Decode as Json
import Json.Decode exposing ((:=))
import Dict exposing (Dict, fromList, toList)
import ZZZFetchJSON exposing (..)
-- MODEL
type alias Comment =
{ body : String }
type alias Post =
{ body : String
, comments : List Comment
}
type alias User =
{ name : String
, username : String
, posts : List Post
}
type alias Model =
{ users : Maybe (Dict Int User)
}
-- MAIN
main =
program
{ init = init
, subscriptions = always Sub.none
, update = update
, view = view
}
-- MESSAGE
type Msg
= DataFetched (Dict Int User)
-- INIT
die : a -> b
die _ =
Debug.crash "dead"
fetchUsers = (Http.get (Json.list userDecoder) usersUrl)
fetchPosts = (Http.get (Json.list postDecoder) postsUrl)
fetchComments = (Http.get (Json.list commentDecoder) commentsUrl)
fetchData : Task Http.Error (Dict Int User)
fetchData = Task.pmap3 combine fetchUsers fetchPosts fetchComments
init : ( Model, Cmd Msg )
init =
( { users = Nothing }
, Task.perform die DataFetched fetchData )
-- UPDATE
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
DataFetched users' ->
{ model | users = Just users' }
-- THE CODE AFTER THIS LINE CAN BE IGNORED FOR THIS DISCUSSION AND IT IS BAD. THANKS :D
--
-- VIEW
view : Model -> Html Msg
view model =
case model.users of
Just users ->
div []
[ ul [] <|
List.map
(\( id, u ) ->
li []
[ text (toString id ++ " " ++ u.name)
, ul [] <|
List.map
(\p ->
li []
[ text p.body
, ul [] <|
List.map
(\c ->
li [] [ text c.body ]
)
p.comments
]
)
u.posts
]
)
(toList users)
]
Nothing ->
div []
[ text "Waiting..."
, div [] [ text (toString model) ]
]
-- COMBINING THE VALUE
combine : List JsonUser -> List JsonPost -> List JsonComment -> Dict Int User
combine jUsers jPosts jComments =
List.map
(\u ->
( u.id
, { name = u.name
, username = u.username
, posts =
List.filterMap
(\p ->
if p.userId == u.id then
Just (combinePost p jComments)
else
Nothing
)
jPosts
}
)
)
jUsers
|> Dict.fromList
combinePost : JsonPost -> List JsonComment -> Post
combinePost jPost allComments =
{ body = jPost.body
, comments =
List.filterMap
(\c ->
if c.postId == jPost.id then
Just { body = c.body }
else
Nothing
)
allComments
}
module ZZZFetchJSON exposing (..)
-- This is just for fetching and decoding some related JSON data
import Json.Decode as Json
import Json.Decode exposing ((:=))
usersUrl =
"https://jsonplaceholder.typicode.com/users"
postsUrl =
"https://jsonplaceholder.typicode.com/posts"
commentsUrl =
"https://jsonplaceholder.typicode.com/comments"
type alias JsonUser =
{ id : Int, name : String, username : String }
type alias JsonPost =
{ id : Int, userId : Int, body : String }
type alias JsonComment =
{ id : Int, postId : Int, body : String }
userDecoder : Json.Decoder JsonUser
userDecoder =
Json.object3 JsonUser
("id" := Json.int)
("name" := Json.string)
("username" := Json.string)
postDecoder : Json.Decoder JsonPost
postDecoder =
Json.object3 JsonPost
("id" := Json.int)
("userId" := Json.int)
("body" := Json.string)
commentDecoder : Json.Decoder JsonComment
commentDecoder =
Json.object3 JsonComment
("id" := Json.int)
("postId" := Json.int)
("body" := Json.string)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment