Introduction

I just pieced this together after reading and looking at examples from the official elm guides. It makes use of an HTTP request to the Spotify API, and an instance of the json decoder to extract the image url from the response and displays it. There’s a search bar that allows you to specify the artist’s picture that you want, and a searching status bar that will indicate the status of your search.

module Nested exposing (..)

import Html exposing (..)
import Http exposing (get, send)
import Html.Events exposing (onClick, onInput)
import Html.Attributes exposing (src, style)
import Json.Decode exposing (at, int, string, list, decodeString, Decoder)
import Json.Decode.Pipeline exposing (decode, required, requiredAt, optional, hardcoded)


-- Spotify Artist Decoders


type alias Artist =
    { name : String
    , uri : String
    , images : List String
    }


imageDecoder : Decoder String
imageDecoder =
    at [ "url" ] string


artistDecoder : Decoder Artist
artistDecoder =
    decode Artist
        |> required "name" string
        |> required "uri" string
        |> required "images" (list imageDecoder)


type alias ArtistList =
    { artists : List Artist }


artistObjectDecoder : Decoder ArtistList
artistObjectDecoder =
    decode ArtistList
        |> requiredAt [ "artists", "items" ] (list artistDecoder)



-- Functions returning messages or impure actions


updateSearchCriteria : String -> Msg
updateSearchCriteria text =
    UpdateSearchCriteria text


getSpotifyArtist : String -> Cmd Msg
getSpotifyArtist name =
    let
        url =
            "https://api.spotify.com/v1/search?q=" ++ name ++ "&type=artist"
    in
        Http.send NewArtist (Http.get url artistObjectDecoder)



-- MODEL/VIEW/UPDATE


type alias Model =
    { results : String
    , searchCriteria : String
    , artistPic : String
    , isSearching : Bool
    }


model : Model
model =
    Model "" "" "" False


init : ( Model, Cmd Msg )
init =
    ( model, Cmd.none )


view : Model -> Html Msg
view model =
    let
        ( fontColor, searchText ) =
            if (model.isSearching) then
                ( "red", "Searching" )
            else
                ( "green", "Done" )
    in
        div []
            [ div [ style [ ( "color", fontColor ) ] ] [ text searchText ]
            , input [ onInput updateSearchCriteria ] []
            , button [ onClick Search ] [ text "Search" ]
            , div [] [ text model.results ]
            , img
                [ (src
                    (if String.length model.artistPic > 0 then
                        model.artistPic
                     else
                        "http://www.graphics99.com/wp-content/uploads/2012/07/simpsons-with-his-small-family.jpg"
                    )
                  )
                ]
                []
            ]


type Msg
    = None
    | UpdateSearchCriteria String
    | NewArtist (Result Http.Error ArtistList)
    | Search


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        None ->
            ( model, Cmd.none )

        UpdateSearchCriteria text ->
            ( { model | searchCriteria = text }, Cmd.none )

        NewArtist json ->
            case json of
                Ok x ->
                    let
                        ( name, pic ) =
                            case (List.head x.artists) of
                                Just a ->
                                    let
                                        pic =
                                            case List.head a.images of
                                                Just pic_url ->
                                                    pic_url

                                                Nothing ->
                                                    "Nothing"
                                    in
                                        ( a.name, pic )

                                Nothing ->
                                    ( "Broken", "No Image" )
                    in
                        ( { model | artistPic = pic, results = name, isSearching = False }, Cmd.none )

                Err msg ->
                    ( { model | results = toString msg, isSearching = False }, Cmd.none )

        Search ->
            ( { model | isSearching = True }, getSpotifyArtist model.searchCriteria )


main : Program Never Model Msg
main =
    Html.program
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }



-- SUBSCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.none

Conclusion

Check it out here (Just a heads up, it probably needs some styling :p)