Elm: attribute “onerror” adds “data-onerror” attribute instead

  • A+
Category:Languages

In Elm I have a simple image, and I want it to be replaced by some 'missing' image onerror. So I added an "onerror" attribute:

img     [ src "broken-link.png"     , attribute "onerror" "this.onerror=null;this.src='missing.png';"     ] [] 

However, when I look at the generated html, the img doesn't get an onerror attribute, but rather gets an data-onerror, and ofcourse this doesn't work.

Why is this? And how do I fix it?

Here is a little example I made with my friend Bulbasaur to illustrate the problem: https://ellie-app.com/3Yn8Y6Rmvrqa1

 


Why is this?

This seems to be a built-in undocumented safety feature of Elm.

Checking source code of Elm, Html.attribute is defined as (source)

attribute : String -> String -> Attribute msg attribute =     VirtualDom.attribute 

and VirtualDom.attribute is defined as (source):

attribute : String -> String -> Attribute msg attribute key value =     Elm.Kernel.VirtualDom.attribute         (Elm.Kernel.VirtualDom.noOnOrFormAction key)         (Elm.Kernel.VirtualDom.noJavaScriptOrHtmlUri value) 

Your attribute name onclick is passed to Elm.Kernel.VirtualDom.noOnOrFormAction which is defined in JavaScript as (source):

function _VirtualDom_noOnOrFormAction(key) {     return /^(on|formAction$)/i.test(key) ? 'data-' + key : key; } 

So if attribute name starts with on, or is string formAction, then it is renamed to be a data-attribute.

How do I fix it?

One way I know how to fix this is to write the code in Elm without JavaScript. Here's full working example with main parts copied below: (This is based on accepted answer here about detecting image load failure.)

1) Keep current URL in model

type alias Model =     { src : String     }  init : Model init =     { src = "http://example.com" } 

2) Change event handler to send Elm message on image load error

img     [ src model.src     , on "error" (Json.Decode.succeed ImageError)     , alt "Should be Bulbasaur"     ] [] 

3) Change URL in update on error

update : Msg -> Model -> Model update msg model =     case msg of         ImageError ->             { model                 | src = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png"             } 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: