I am working on a basic decoding-json Elm example for practice but can not figure out the Elm compilation errors. I also am confused why this runs in Ellie (that is with a remote JSON URL) but not when compiled locally using Elm v 19.0 FYI.
The goal was to make a simple call to get JSON from a Go server but just compiling the example Elm I got from the documentation for decoding JSON is not working out so here we are.
module HelloWorld exposing (..)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http
import Json.Decode exposing (Decoder, field, string)
-- MAIN
main =
Browser.element
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- MODEL
type Model
= Failure
| Loading
| Success String
init : () -> (Model, Cmd Msg)
init _ =
(Loading, getRandomCatGif)
-- UPDATE
type Msg
= MorePlease
| GotGif (Result Http.Error String)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
MorePlease ->
(Loading, getRandomCatGif)
GotGif result ->
case result of
Ok url ->
(Success url, Cmd.none)
Err _ ->
(Failure, Cmd.none)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Html Msg
view model =
div []
[ h2 [] [ text "Random Cats" ]
, viewGif model
]
viewGif : Model -> Html Msg
viewGif model =
case model of
Failure ->
div []
[ text "I could not load a random cat for some reason. "
, button [ onClick MorePlease ] [ text "Try Again!" ]
]
Loading ->
text "Loading..."
Success url ->
div []
[ button [ onClick MorePlease, style "display" "block" ] [ text "More Please!" ]
, img [ src url ] []
]
-- HTTP
getRandomCatGif : Cmd Msg
getRandomCatGif =
Http.get
{ url = "http://127.0.0.1:8080/test"
, expect = Http.expectJson GotGif gifDecoder
}
gifDecoder : Decoder String
gifDecoder =
field "data" (field "image_url" string)
and now the go server
// write json back to elm call
package main
import (
"fmt"
"log"
"net/http"
"os"
"github.com/gorilla/schema"
)
type ToDo struct {
Title string
Description string
}
func main() {
http.HandleFunc("/test", test)
http.ListenAndServe(getPort(), nil)
}
func getPort() string {
p := os.Getenv("PORT")
if p != "" {
return ":" + p
}
return ":8080"
}
func test(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
//Allow CORS here By * or specific origin
w.Header().Set("Access-Control-Allow-Origin", "*")
// say hi
fmt.Fprintf(w, "hello from go"+"\n")
} else {
//Allow CORS here By * or specific origin
w.Header().Set("Access-Control-Allow-Origin", "*")
todo := readForm(r)
fmt.Fprintf(w, "updated todo to"+todo.Title+"\n")
}
}
func readForm(r *http.Request) *ToDo {
r.ParseForm()
todo := new(ToDo)
decoder := schema.NewDecoder()
decodeErr := decoder.Decode(todo, r.PostForm)
if decodeErr != nil {
log.Printf("error mapping parsed form data to struct : ", decodeErr)
}
return todo
}
and finally the ELM errors elm make ./src/HelloWorld.elm
Detected problems in 1 module.
-- TYPE MISMATCH -------------------------------------------- src/HelloWorld.elm
Something is off with the body of the `getRandomCatGif` definition:
110|> Http.get
111|> { url = "http://127.0.0.1:8080/test"
112|> , expect = Http.expectJson GotGif gifDecoder
113|> }
This `get` call produces:
Decoder a -> Http.Request a
But the type annotation on `getRandomCatGif` says it should be:
Cmd Msg
-- TYPE MISMATCH -------------------------------------------- src/HelloWorld.elm
The 1st argument to `get` is not what I expect:
110| Http.get
111|> { url = "http://127.0.0.1:8080/test"
112|> , expect = Http.expectJson GotGif gifDecoder
113|> }
This argument is a record of type:
{ expect : b, url : String }
But `get` needs the 1st argument to be:
String
-- TYPE MISMATCH -------------------------------------------- src/HelloWorld.elm
The 1st argument to `expectJson` is not what I expect:
112| , expect = Http.expectJson GotGif gifDecoder
^^^^^^
This `GotGif` value is a:
Result Http.Error String -> Msg
But `expectJson` needs the 1st argument to be:
Decoder a
-- TOO MANY ARGS -------------------------------------------- src/HelloWorld.elm
The `expectJson` function expects 1 argument, but it got 2 instead.
112| , expect = Http.expectJson GotGif gifDecoder
^^^^^^^^^^^^^^^
Are there any missing commas? Or missing parentheses?
It looks like you've installed version 1.0.0 of the elm/http
module whereas the example requires elm/http
version 2.0.0. I could reproduce your errors with version 1.0.0 of this package, but the code compiled successfully with 2.0.0.
Edit your elm.json
file to change the version of elm/http
to 2.0.0
and try running elm make ...
again.