Reputation: 21637
Giving the model (related to this):
type alias ValidationResult =
{ parameter : String
, errorMessage : String
}
type alias ErrorResponse =
{ validationErrors : List ValidationResult }
decodeValidationResults : Decoder ValidationResult
decodeValidationResults =
map2 ValidationResult
(field "Parameter" string)
(field "ErrorMessage" string)
decodeErrorResponse : Decoder ErrorResponse
decodeErrorResponse =
map ErrorResponse
(field "ValidationErrors" (list decodeValidationResults))
I want to create a function that returns the forst error message from the ErrorResponse. Here is what I've tried:
firstErrorMessage : Decoder CardEngineErrorResponse -> String
firstErrorMessage decoder response =
case List.head response.validationErrors of
Just something ->
something.errorMessage
Nothing ->
toString ""
But I'm getting the error:
The definition of `firstErrorMessage` does not match its type annotation.
The type annotation for `firstErrorMessage` says it always returns:
String
But the returned value (shown above) is a:
{ b | validationErrors : List { a | errorMessage : String } } -> String
Hint: It looks like a function needs 1 more argument.
Any of you have any idea what I am doing wrong?
Upvotes: 0
Views: 104
Reputation: 36375
If you are just trying to get the first error message from an ErrorResponse
value, you don't need to reference Decoder
:
firstErrorMessage : ErrorResponse -> String
firstErrorMessage response =
case List.head response.validationErrors of
Just something ->
something.errorMessage
Nothing ->
""
or, more succinctly:
firstErrorMessage : ErrorResponse -> String
firstErrorMessage response =
List.head response.validationErrors
|> Maybe.map .errorMessage
|> Maybe.withDefault ""
If you are instead trying to do this all within context of a decoder, you can do so using Json.Decode.map
:
firstErrorMessageDecoder : Decoder String
firstErrorMessageDecoder =
decodeErrorResponse
|> map firstErrorMessage
One more note: When something has the possibility of failing, it is often best to retain the notion of Maybe
. Instead of defaulting to the empty string which callers will have to know about, you can build a stronger API by returning a Maybe String
:
firstErrorMessage : ErrorResponse -> Maybe String
firstErrorMessage response =
List.head response.validationErrors
|> Maybe.map .errorMessage
Upvotes: 2