These are chat archives for ThoughtWorksInc/Binding.scala

6th
May 2016
Anthony Homan
@anthonyhoman
May 06 2016 02:53
Hey everybody. I would appreciate any help on a problem I'm having. I threw together a quick reactive router app. It works fine if I hard-code the link targets. But if I try to pass in values from a States configuration object, I get a null reference error. What am I overlooking? Thanks
object ExampleApp extends js.JSApp {

  object Router {
    val stateMap: Map[String,State] = {
      Seq(States.homeState, States.nextState).foldLeft(Map[String,State]())((m,s) => m.updated(s.hash, s))
    }
    def getCurrentState: State = {
      stateMap.get(window.location.hash).getOrElse(States.homeState)
    }

    @dom def containerComponent = {
      <div>{ currentState.each.component.each }</div>
    }

    val currentState = Var(getCurrentState)
    @dom val hashBinding = window.location.hash = currentState.each.hash
    hashBinding.watch()
    window.onhashchange = { _: Any =>  currentState := getCurrentState }
  }

  final case class State(text: String, hash: String, component: Binding[Node])

  object States {
    val homeState: State = State("home", "#/", HomeComponent.content)
    val nextState: State = State("next", "#/next", NextComponent.content)
  }

  object HomeComponent {
    @dom def content = {
      <a href={ Constant(States.nextState.hash).each }>Next State</a>
    }
  }

  object NextComponent {
    @dom def content = {
      <a href={ Constant(States.homeState.hash).each }>Home State</a>
    }
  }

  def main() = dom.render(document.body, Router.containerComponent)
}
杨博 (Yang Bo)
@Atry
May 06 2016 03:52
I guess you could make componet call-by-name, i.e component: => Binding[Node] instead of component: Binding[Node]
@anthonyhoman FYI
Anthony Homan
@anthonyhoman
May 06 2016 04:19
That was it! Was pulling my hair out. Thank you. I ended up making component a function param so I could still use the State case class, and then it worked
Rahel Lüthy
@netzwerg
May 06 2016 07:36

Hey there – I am evaluating Bindings.scala for a future project and I love it so far! However, I am struggling with IntelliJ's editor:

object D3Chart {

  @dom
  def chart: Binding[Div] = {

    val div: Div = <div id="d3"></div>

    val svg = d3.
      select(div).
      append("svg").
      attr("width", "100%").
      attr("height", 400)

    svg
      .append("text")
      .text("Hello from D3")
      .attr("y", 50)

    div
  }  // <-- Editor complains here

}

The message I get is:

Expression of type html.Div doesn't conform to expected Binding[html.Div]

If I wrap the final line in an artificial div, everything works fine:

<div>{div}</div>

I guess IntelliJ is struggling with the macro, right? Any tips? Here's the version I'am using:

IntelliJ IDEA 2016.1
Build #IU-145.970, built on April 18, 2016
JRE: 1.8.0_76-release-b162 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o

Tia!

Btw: The editor is showing a red mark, it compiles just fine...
杨博 (Yang Bo)
@Atry
May 06 2016 07:42
You could try Scala IDE for Eclipse, it does not show red mark @netzwerg
Rahel Lüthy
@netzwerg
May 06 2016 07:44
I'd rather not switch to a different IDE ;-) I was just hoping that someone else was maybe also using IntelliJ 2016.1 and could offer some help...
杨博 (Yang Bo)
@Atry
May 06 2016 07:53
I found that IntelliJ is very slow for complicated Scala embedded XML literals, and its auto-formating for code is terrible for XML interpolation, too.
I guess you could vote this bug: https://youtrack.jetbrains.com/issue/SCL-9091
Rahel Lüthy
@netzwerg
May 06 2016 07:57
Tx, I voted for the bug!
杨博 (Yang Bo)
@Atry
May 06 2016 08:05
Scala IDE for Eclipse expands @dom macros when type checking. Unfortunately, IntelliJ IDEA does not. I also suggest Atom or other plain HTML editor for embedded XHTML templates.