Skip to content

Warn if ChildNode is used as modifier multiple times. #184

@raquo

Description

@raquo

Discussed in #183

Originally posted by ivan-klass January 22, 2025
Recently, I've encountered an issue with some elements being not displayed where expected.

Here's a simplified and minimized example to demonstrate my case:

See https://scastie.scala-lang.org/8dB25QZfRtW0ZuamN4x88w

import com.raquo.laminar.api.L.{*, given}
import org.scalajs.dom
import scala.scalajs.js

val brick = span("[BRICK]", styleAttr := "background-color: orange")
val tenBricks = div(Seq.fill(10)(brick)*) // won't contain 10 children in practice

// A helper to render Laminar elements in Scastie
def renderApp(app: dom.Element, content: => Element) =
  js.timers.setTimeout(0) { render(app, content) }
  app

renderApp(dom.document.createElement("div"), tenBricks) // renders only one brick, no warning

The root case traces back to a lack of referential transparency: an expression of the node declaration can't be assigned to a val and reused. That's because there is an allocation side-effect, which is probably fine to have as Laminar don't pretend to be FP framework. With mixed feelings, I've completely fixed my particular problem by simply changing val definition to def.

If I understand correctly, using an element as a modifier is equivalent to setting a parent, and the most common case is when there were no parent before.

Given the above, I think maybe it would make sense to have a warning when element is used as modifier while the parent is already set. In case when changing the parent was intentional, maybe it's better to have an explicit mechanism (e.g. method, function, event) for that, rather than using modifier syntax?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions