Created
August 24, 2016 07:47
-
-
Save cobalamin/9ce56dcd6e3da7f30f1f0ba58b1b9874 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module FetchParallel 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 Intermediate = | |
| { users : Maybe (List JsonUser) | |
| , posts : Maybe (List JsonPost) | |
| , comments : Maybe (List JsonComment) | |
| } | |
| emptyIntermediate : Intermediate | |
| emptyIntermediate = | |
| { users = Nothing | |
| , posts = Nothing | |
| , comments = Nothing | |
| } | |
| type alias Model = | |
| { users : Maybe (Dict Int User) | |
| , intermediate : Intermediate | |
| } | |
| -- MAIN | |
| main = | |
| program | |
| { init = init | |
| , subscriptions = always Sub.none | |
| , update = update | |
| , view = view | |
| } | |
| -- MESSAGE | |
| type Msg | |
| = UsersFetched (List JsonUser) | |
| | PostsFetched (List JsonPost) | |
| | CommentsFetched (List JsonComment) | |
| -- INIT | |
| die : a -> b | |
| die _ = | |
| Debug.crash "dead" | |
| init : ( Model, Cmd Msg ) | |
| init = | |
| ( { users = Nothing | |
| , intermediate = emptyIntermediate | |
| } | |
| , Cmd.batch | |
| [ Task.perform die UsersFetched (Http.get (Json.list userDecoder) usersUrl) | |
| , Task.perform die PostsFetched (Http.get (Json.list postDecoder) postsUrl) | |
| , Task.perform die CommentsFetched (Http.get (Json.list commentDecoder) commentsUrl) | |
| ] | |
| ) | |
| -- UPDATE | |
| update : Msg -> Model -> ( Model, Cmd Msg ) | |
| update msg model = | |
| case msg of | |
| UsersFetched users -> | |
| let | |
| intermediate = | |
| model.intermediate | |
| in | |
| tryCombine { model | intermediate = { intermediate | users = Just users } } ! [] | |
| PostsFetched posts -> | |
| let | |
| intermediate = | |
| model.intermediate | |
| in | |
| tryCombine { model | intermediate = { intermediate | posts = Just posts } } ! [] | |
| CommentsFetched comments -> | |
| let | |
| intermediate = | |
| model.intermediate | |
| in | |
| tryCombine { model | intermediate = { intermediate | comments = Just comments } } ! [] | |
| tryCombine : Model -> Model | |
| tryCombine ({ intermediate } as model) = | |
| { model | users = Maybe.map3 combine intermediate.users intermediate.posts intermediate.comments } | |
| -- 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 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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