-
-
Save imnutz/bf826e7d1b0500f3d64f to your computer and use it in GitHub Desktop.
Getting the Reddit Home Page using Elm Promises
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
| import Html exposing (..) | |
| import Html.Events exposing (..) | |
| import Html.Attributes exposing (href, style, src) | |
| import Task exposing (Task) | |
| import Http exposing (Error) | |
| import JavaScript.Decode exposing (..) | |
| -- Operator from Clojure | |
| (>!) : a -> Stream.Input a -> Stream.Message | |
| (>!) a input' = Stream.message input'.address a | |
| -- Javascript Decoding Helper | |
| andMap : Decoder (a -> b) -> Decoder a -> Decoder b | |
| andMap = object2 (<|) | |
| -- Model + Javascript Parsing | |
| type alias RedditPostData = | |
| { url : String | |
| , title : String | |
| , score : Int | |
| } | |
| redditPostData : Decoder RedditPostData | |
| redditPostData = RedditPostData | |
| `map` ("url" := string) | |
| `andMap` ("title" := string) | |
| `andMap` ("score" := int) | |
| type alias RedditPost = | |
| { data : RedditPostData } | |
| redditPost : Decoder RedditPost | |
| redditPost = RedditPost | |
| `map` ("data" := redditPostData ) | |
| type alias RedditListingData = | |
| { children : List RedditPost } | |
| redditListingData : Decoder RedditListingData | |
| redditListingData = RedditListingData | |
| `map` ("children" := list redditPost) | |
| type alias RedditListing = | |
| { data : RedditListingData } | |
| redditListing : Decoder RedditListing | |
| redditListing = RedditListing | |
| `map` ("data" := redditListingData) | |
| testRedditListing : RedditListing | |
| testRedditListing = | |
| { data = { children = [] } } | |
| -- The Reddit Homepage! | |
| redditUrl : String | |
| redditUrl = | |
| "https://www.reddit.com/.json" | |
| -- The main promise | |
| requestListing : String -> Task Error RedditListing | |
| requestListing url = | |
| Http.get redditListing url | |
| -- The query we send | |
| input query : Stream.Input String | |
| -- The results from the query | |
| input results : Stream (Result Error RedditListing) | |
| input results from | |
| Stream.map requestListing query.stream | |
| -- VIEW | |
| -- View an individual Reddit post | |
| viewPost : RedditPost -> Html | |
| viewPost { data } = | |
| let | |
| scoreStyle = style | |
| [("height", "50px") | |
| ,("flex", "1") | |
| ,("align-self", "center") | |
| ] | |
| itemStyle = style | |
| [("display", "flex") | |
| ,("margin-bottom", "10px") | |
| ] | |
| linkStyle = style | |
| [("flex", "8") | |
| ,("align-self", "flex-start") | |
| ] | |
| in | |
| li [ itemStyle ] | |
| [ div [ scoreStyle ] | |
| [ text (toString data.score) ] | |
| , | |
| a | |
| [ linkStyle | |
| , href data.url | |
| ] | |
| [ div [] [text data.title] ] | |
| ] | |
| elmLogo : Html | |
| elmLogo = | |
| let | |
| logoStyle = style | |
| [("height", "50px") | |
| ,("width", "50px") | |
| ,("min-height", "40px") | |
| ,("min-width", "40px") | |
| ,("flex", "1") | |
| ] | |
| in | |
| img | |
| [ src "http://elm-lang.org/logo.svg" | |
| , logoStyle | |
| ][] | |
| clientHeader : Html | |
| clientHeader = | |
| let | |
| headerStyle = style | |
| [ ("display", "flex") | |
| , ("align-items", "center") | |
| ] | |
| textStyle = style | |
| [ ("flex", "8") ] | |
| in | |
| header [ headerStyle ] | |
| [ elmLogo | |
| , div [ textStyle ] [ text "Reddit Client in Elm" ] | |
| ] | |
| -- Global view function | |
| view : Result Error RedditListing -> Html | |
| view listingResult = case listingResult of | |
| Err error -> | |
| button | |
| [ onClick (redditUrl >! query) ] | |
| [ text "Get Reddit Front Page" ] | |
| Ok listing -> | |
| div [] | |
| [ clientHeader | |
| , ul [] | |
| (List.map viewPost listing.data.children) | |
| ] | |
| -- Main Function | |
| main : Varying Html | |
| main = | |
| Varying.map view | |
| (Varying.fromStream (Err Http.Timeout) results) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment