Skip to content

Instantly share code, notes, and snippets.

@SirmaXX
Created August 30, 2019 05:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SirmaXX/895e18b307f9f60c19edce34412d3a9f to your computer and use it in GitHub Desktop.
Save SirmaXX/895e18b307f9f60c19edce34412d3a9f to your computer and use it in GitHub Desktop.
Http get and post in elm app
module Main exposing (Msg(..), Post, init, main, postBlog, postBlogFromid, postDecoder, sendPost, subscriptions, update, view, viewPost, viewPosts, viewedit)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http exposing (Error(..))
import Json.Decode exposing (Decoder, field, float, int, map2, string)
import Json.Encode as Encode
-- MAIN
main =
Browser.element
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
apiUrl : String
apiUrl =
"https://my-json-server.typicode.com/typicode/demo/posts/"
-- MODEL
--data structure for decoder and post
type alias Post =
{ id : Int
, title : String
}
type alias Model =
{ id : Int
, title : String
, status : HttpStatus
}
type HttpStatus
= Failure Http.Error
| Loading
| Success (List Post)
| SuccessOne Post
init : () -> ( Model, Cmd Msg )
init _ =
( { id =4 , title = "", status = Loading }, postBlog )
type Msg
= GetPost
| Getid String
| PostList (Result Http.Error (List Post))
| OnePost (Result Http.Error Post)
| Gettitle String
| SendData
-- UPDATE
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
GetPost ->
( { id=4, title = "", status = Loading }
,
postBlogFromid (String.fromInt(model.id))
)
Getid postid ->
( { model | id = (Maybe.withDefault 0 (String.toInt(postid))) }, Cmd.none )
PostList result ->
case result of
Ok url ->
( { model | status = Success url }, Cmd.none )
Err error ->
( { model | status = Failure error }, Cmd.none )
OnePost result ->
case result of
Ok url ->
( { model | status = SuccessOne url }, Cmd.none )
Err error ->
( { model | status = Failure error }, Cmd.none )
Gettitle posttitle ->
( { model | title = posttitle }, Cmd.none )
SendData ->
( { model | id = 1, title = "", status = Loading }, sendPost model.id model.title )
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Html Msg
view model =
div []
[ h2 [] [ text "find blog" ]
, viewPosts model
]
viewPosts : Model -> Html Msg
viewPosts model =
case model.status of
Failure error ->
div []
[ viewError error
, input
[ placeholder "enter a posts id"
, value (String.fromInt(model.id))
, autofocus True
, onInput Getid
]
[]
,button [ onClick GetPost ] [ text "GetPost" ]
, viewedit model
, button [ onClick GetPost ] [ text "Try Again!" ]
]
Loading ->
text "Loading..."
Success posts ->
div []
[ input
[ placeholder "enter a posts id"
, value (String.fromInt(model.id))
, autofocus True
, onInput Getid
]
[]
, button [ onClick GetPost ] [ text "GetPost" ]
, viewedit model
, pre [] (List.map viewPost posts)
]
SuccessOne post ->
div []
[ input
[ placeholder "enter a posts id"
, value (String.fromInt(model.id))
, autofocus True
, onInput Getid
]
[]
, button [ onClick GetPost ] [ text "GetPost" ]
, viewedit model
, viewPost post
]
viewedit : Model -> Html Msg
viewedit model =
div []
[ h2 [] [ text "create post" ]
, input
[ placeholder "title"
, value (String.fromInt(model.id))
, onInput Getid
]
[]
, input
[ placeholder "title"
, value model.title
, onInput Gettitle
]
[]
, button [ onClick SendData ] [ text "GetPost" ]
]
viewPost : Post -> Html a
viewPost post =
table []
[ tr []
[ th [] [ text "id" ]
, th [] [ text "userid" ]
, th [] [ text "title" ]
]
, tr []
[ td [] [ text <| "" ++ String.fromInt post.id ++ "" ]
, td [] [ text <| "" ++ post.title ++ "" ]
, td [] [ a [ href "" ] [ text "Edit" ] ]
]
]
viewError : Http.Error -> Html a
viewError error =
let
( header, message ) =
case error of
BadUrl string ->
( "Bad URL", string )
Timeout ->
( "The server did not respond", "" )
NetworkError ->
( "Network error", "" )
BadStatus code ->
( "HTTP Error " ++ String.fromInt code, "" )
BadBody string ->
( "JSON decoding error", string )
in
div []
[ h3 [] [ text header ]
, pre [] [ text message ]
]
-- HTTP
--its get posts for jsonplaceholder
sendPost id title =
Http.post
{ url = apiUrl
, body = Http.jsonBody (postEncoder id title)
, expect = Http.expectJson OnePost postDecoder
}
postBlog : Cmd Msg
postBlog =
Http.get
{ url = "https://my-json-server.typicode.com/typicode/demo/posts/"
, expect = Http.expectJson PostList (Json.Decode.list postDecoder)
}
postBlogFromid : String -> Cmd Msg
postBlogFromid blogid =
Http.get
{ url = "https://my-json-server.typicode.com/typicode/demo/posts/" ++ blogid
, expect = Http.expectJson OnePost postDecoder
}
--decoder for json items
postDecoder : Decoder Post
postDecoder =
map2 Post
(field "id" int)
(field "title" string)
postEncoder : Int -> String -> Encode.Value
postEncoder id title =
Encode.object
[ ( "id", Encode.int id )
, ( "title", Encode.string title )
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment