Created
August 30, 2019 05:03
-
-
Save SirmaXX/895e18b307f9f60c19edce34412d3a9f to your computer and use it in GitHub Desktop.
Http get and post in elm app
This file contains 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 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