Skip to content

Instantly share code, notes, and snippets.

@imnutz
Forked from TheSeamau5/RedditHomePage.elm
Last active August 29, 2015 14:25
Show Gist options
  • Select an option

  • Save imnutz/bf826e7d1b0500f3d64f to your computer and use it in GitHub Desktop.

Select an option

Save imnutz/bf826e7d1b0500f3d64f to your computer and use it in GitHub Desktop.
Getting the Reddit Home Page using Elm Promises
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