2

I tried the following code to render json into dom but failed

       <div class="row">
        {val result = FutureBinding(ApiHomeProjectsGet.request())
      result.bind match {
        case None => <div>Loading...</div>
        case Some(Success(ApiHomeProjectsGetResponse200(projects))) =>     {
          for (project <- projects.items) yield <p> {project.title} </p>
        }
        case e => <div>Error</div>
      }}
      </div>

projects is defined as a case class

case class Projects(items: ArrayBuffer[Project])

the compiler reports error:

overloaded method value domBindingSeq with alternatives:
[error]   (text: String)com.thoughtworks.binding.Binding.Constants[org.scalajs.dom.raw.Text] <and>
[error]   (node: org.scalajs.dom.raw.Node)com.thoughtworks.binding.Binding.Constants[org.scalajs.dom.raw.Node] <and>
[error]   (seq: Seq[org.scalajs.dom.raw.Node])com.thoughtworks.binding.Binding.Constants[org.scalajs.dom.raw.Node] <and>
[error]   (bindingSeq: com.thoughtworks.binding.Binding.BindingSeq[org.scalajs.dom.raw.Node])com.thoughtworks.binding.Binding.BindingSeq[org.scalajs.dom.raw.Node]
[error]  cannot be applied to (Object)
[error]           <div class="row">
[error]            ^
[error] one error found

How can I render json data from api request to dom with the for(...) yield pattern?


The best solution

     case Some(Success(ApiHomeProjectsGetResponse200(projects))) =>
        <div class="row">
          {Constants[Project](projects.items:_*).map(item => <p> {item.title} </p>)}
        </div>

2 Answers 2

1

According to your definition of Projects, projects.items is of type ArrayBuffer[Project]. Your for comprehension desugars to map, the result is therefore of type ArrayBuffer[dom.raw.Node].

In your pattern matching expression you are mixing dom.raw.Node and ArrayBuffer[dom.raw.Node], the least upper bound of these two types is Object which is why it pops up in the error message.

One way to solve this problem would be to return a dom.raw.Node in every branch of the pattern matching, for example:

case ... =>
  <div>
    (for (project <- projects.items) yield <p> {project.title} </p>).toSeq
  </div>
Sign up to request clarification or add additional context in comments.

2 Comments

I try to use the following code ` case Some(Success(ApiHomeProjectsGetResponse200(projects))) => <div> (for (project <- projects.items) yield <p>{project.title}</p>).toSeq </div>`
but still get errors: in XML literal: name expected, but char '-' cannot start a name [error] (for (project <- projects.items) yield <p>{project.title}</p>).toSeq
0

For now, I can use a render function to solve this problem

          case Some(Success(ApiHomeProjectsGetResponse200(projects))) =>
          val projectsBinding = Vars[Project](projects.items:_*)
          <div>
             { renderProjectPanel(projectsBinding).bind}
          </div>

          @dom def renderProjectPanel(items: Vars[Project]) = {
              for (project <- items) yield <p>{project.title}</p>
          }

even though this needs to add some more code, but it works

Hope someone will give a simpler solution

1 Comment

Vars should be Constants, see stackoverflow.com/questions/42498968/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.