svg
svg copied to clipboard
Runtime error when passing `class` attribute from Html package.
When attempting to add a class name to an SVG element using class
from the elm-lang/html
package the compiler doesn't complain. When running the compiled program an error is thrown:
Uncaught TypeError: Cannot set property className of #<SVGElement> which has only a getter
It's a stupid mistake, but still, when working with some SVG content nested in an HTML view it's not unlikely to happen.
Below is a sample program that produces the error.
module Main exposing (..)
import Html.App as Html
import Svg exposing (..)
import Html.Attributes exposing (class)
view : () -> Svg Never
view model =
svg []
[ g [ class "html-class" ]
[]
]
main : Program Never
main =
Html.beginnerProgram { model = (), view = view, update = \_ _ -> () }
Happened to me as well.
I had the same problem.
@evancz Why class
functions from Html and Svg modules have incompatible implementations?
-- From Html.Attributes
-- className property can't be used for svg nodes
class value =
VirtualDom.property "className" (Json.string value)
-- From Svg.Attributes
class value =
VirtualDom.attribute "class" value
SVG does not have JS properties. You can not use properties for anything.
I am just curious why people are mixing and matching between these libraries.
In my case I wasn't intentionally mixing them so once I figured out what went wrong it was easy to fix. Still, it would have been nice if the compiler would have warned me for my stupidity.
I pretty often use inline SVGs in my HTML and I can add class
attribute to almost any element including SVG:
<div class="house">
<svg class="dog">
<path d="" />
</svg>
</div>
So when I first time tried Elm, my intuition failed:
div [ class "house" ]
[ svg [ class "dog", svgContent "<path d='' />" ] []
]
svgContent content =
property "innerHTML" (Json.Encode.string content)
The compiler didn't tell me anything about it. So I got Uncaught TypeError: Cannot set property className...
runtime exception. It's totally my fault coming from my wrong expectations and previous experience.
BTW, if Html.class
implementation would also use VirtualDom.attribute "class" value
approach, it would prevent the problem for other newcomers. I guess it relies on the className
property for performance?
I ran into this problem because I was using inline SVGs. Easy mistake to make any time you're using inline SVGs. Took some digging to realize what I was doing wrong.
I am using inline SVGs a lot a also. I am really don't like this runtime exception since only because of this I am checking every page of my Elm project for this issue (and there still possible runtime issues when state changes for example).
The most bad thing is that elm compiler allows to pass Html.Attributes.class
to functions with definition like this: icon : String -> List (Svg.Attribute msg) -> Svg msg
I had same issue. It would be good if it could be caught by compiler, to help enforce "no runtime exceptions".
I think the issue is that both Svg.Attribute msg
and Html.Attribute msg
are type aliases, which don't enforce strong typing. Don't see an easy solution, without breaking changes. It would be good if elm had something like type alias that enforced strong typing (could use a union type with a single variant but it's a bit messy, and a breaking change).
I just ran into this exact issue today, didn't take long to figure out but still confused because I got a runtime error instead of a compiler error.
Here's what surprised me:
According to the source, Svg.svg
accepts List (Html.Attribute msg)
:
svg : List (Html.Attribute msg) -> List (Svg msg) -> Html.Html msg
My use is embedding SVG in HTML too. I mistakenly added Html.Attribute.class
to Svg.svg
.
To fix it I added a wrapper HTML element (span
) with the class.
I've just ran into the same issue.
Accidentally used Html.Attribute.class
instead of TypedSvg.Attributes.class
.
Yes, it caused a runtime error which was surprising and somewhat disappointing. People are running into this, see the referenced tickets. I also arrived here from such a ticket.
I would suggest going ahead with a breaking change to ensure that the type system can still protect us from runtime errors.
Just wanted to leave here that the same thing happened to me, took me a while to figure out that I had my imports messed up.
I feel like since these types are not compatible, the code shouldn't have compiled (or maybe give a warning). It's a bit sad to see that people have had this issue for 3,5 years now.
Hello from 2020 (what a great year!), I've just spent over an hour wondering why my page fails unexpectedly (and actually goes into infinite loop of updateIfNeeded
), just because I accidentally imported Html.Attributes.class
instead of Svg.Attributes.class
which the compiler happily accepted :-(
I got used so much to Elm's "If it compiles it just works" so I was quite taken aback by this. Not sure which is the correct place to push for fix, whether here or at the elm/compiler but I guess this should really get fixed. Seems like I'm not the only one who stumbled upon this...
Greetings from 2022 :wave:
This bit us as well. Interestingly, this did not cause a fatal runtime error during the development build with the --debug
flag on, and only error-ed out for the production build, which made it significantly more nasty for us
I'm not even using Elm anymore. I guess the ecosystem has just stalled due to the Elm 0.19 release fiasco. These issues may never be fixed.