Elm: decoding json from HTTP response and showing it

I’m kind of new to Elm, and it’s very difficult for me to decode json from an HTTP response.
The application that I am doing is accessing gravatar and getting the profile. I would like to extract some fields from the response and insert into the record, which, in turn, is shown in the view. This is my code:

-- MODEL

type alias MentorRecord =
    { displayName : String
    , aboutMe : String
    , currentLocation : String
    , thumbnailUrl : String
    }

type alias Model =
    { newMentorEmail : String
    , newMentor : MentorRecord
    , mentors : List MentorRecord
    }

init : ( Model, Cmd Msg )
init =
    ( Model "" (MentorRecord "" "" "" "") [], Cmd.none )

-- UPDATE

type Msg
    = MentorEmail String
    | AddMentor
    | GravatarMentor (Result Http.Error MentorRecord)
    | RemoveMentor

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        MentorEmail newEmail ->
            ( { model | newMentorEmail = newEmail }, Cmd.none )
        AddMentor ->
            ( model, getGravatarMentor model.newMentorEmail )
        GravatarMentor (Ok addedMentor) ->
            ( Model "" addedMentor (addedMentor :: model.mentors)
            , Cmd.none
            )
        GravatarMentor (Err _) ->
            ( model, Cmd.none )
        RemoveMentor ->
            ( model, Cmd.none )

-- VIEW
view : Model -> Html Msg
view model =
    div []
        [ input [ placeholder "Email adress mentor", onInput MentorEmail ] []
        , button [ onClick AddMentor ] [ text "Add Mentor" ]
        , br [] []
        , img [ src (createIconUrl model.newMentorEmail) ] []
        , div [] [ text model.newMentor.displayName ]
        , div [] [ toHtmlImgList model.mentors ]
        ]

toHtmlImgList : List MentorRecord -> Html Msg
toHtmlImgList mentors =
    ul [] (List.map toLiImg mentors)

toLiImg : MentorRecord -> Html Msg
toLiImg mentor =
    li [] [ img [ src mentor.thumbnailUrl ] [] ]

-- HTTP

getGravatarMentor : String -> Cmd Msg
getGravatarMentor newMentorEmail =
    Http.send GravatarMentor
        (Http.get (createProfileUrl newMentorEmail) decodeGravatarResponse)

createProfileUrl : String -> String
createProfileUrl email =
    "https://en.gravatar.com/" ++ MD5.hex email ++ ".json"

createIconUrl : String -> String
createIconUrl email =
    "https://www.gravatar.com/avatar/" ++ MD5.hex email

decodeGravatarResponse : Decoder MentorRecord
decodeGravatarResponse =
    let
        mentorDecoder =
            Json.Decode.Pipeline.decode MentorRecord
                |> Json.Decode.Pipeline.required "displayName" string
                |> Json.Decode.Pipeline.required "aboutMe" string
                |> Json.Decode.Pipeline.required "currentLocation" string
                |> Json.Decode.Pipeline.required "thumbnailUrl" string
    in
        at [ "entry" ] mentorDecoder

If a valid email address, if it is filled out (i.e. one with a gravatar profile), an icon is displayed. But this code also has to do is extract the name, location, info about me, thumbnailUrl from another HTTP response, put it in a list and show it in the view. And this does not happen if you click "Add Mentor"

, , , (, ?).

gravatar ( ):

{ "entry": [
    {
    "preferredUsername": "bla",
    "thumbnailUrl": "https://secure.gravatar.com/avatar/hashinghere",
    "displayName": "anne",
    "aboutMe": "Something...",
    "currentLocation": "Somewhere",
    }
]}

Ellie: https://ellie-app.com/n5dxHhvQPa1/1

+4
1

entry - . , Json.Decode.index.

:

(at [ "entry" ]) mentorDecoder

(at [ "entry" ] << index 0) mentorDecoder

, Gravatar - (CORS), JSONP. elm-http JSONP. , CORS . ellie , CORS .

aboutMe currentLocation , , . : https://ellie-app.com/pS2WKpJrFa1/0

:

createProfileUrl : String -> String
createProfileUrl email =
    "https://en.gravatar.com/" ++ MD5.hex email ++ ".json"

decodeGravatarResponse : Decoder MentorRecord
decodeGravatarResponse =
    let
        mentorDecoder =
            Json.Decode.Pipeline.decode MentorRecord
                |> Json.Decode.Pipeline.required "displayName" string
                |> Json.Decode.Pipeline.required "aboutMe" string
                |> Json.Decode.Pipeline.required "currentLocation" string
                |> Json.Decode.Pipeline.required "thumbnailUrl" string
    in
        at [ "entry" ] mentorDecoder

:

createProfileUrl : String -> String
createProfileUrl email =
    "https://crossorigin.me/https://en.gravatar.com/" ++ MD5.hex email ++ ".json"

decodeGravatarResponse : Decoder MentorRecord
decodeGravatarResponse =
    let
        mentorDecoder =
            Json.Decode.Pipeline.decode MentorRecord
                |> Json.Decode.Pipeline.required "displayName" string
                |> Json.Decode.Pipeline.optional "aboutMe" string ""
                |> Json.Decode.Pipeline.optional "currentLocation" string ""
                |> Json.Decode.Pipeline.required "thumbnailUrl" string
    in
    (at [ "entry" ] << index 0) mentorDecoder
+3

Source: https://habr.com/ru/post/1693968/


All Articles