Как отобразить результат json из запроса API с помощью Binding.scala

Я попытался следующий код для рендеринга JSON в DOM, но не удалось

       <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>

Проекты определены как класс дела

case class Projects(items: ArrayBuffer[Project])

компилятор сообщает об ошибке:

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

Как я могу отобразить данные json из API-запроса в DOM с помощью шаблона for(...) yield?


Лучшее решение

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

2 ответа

Согласно вашему определению Projects, projects.items имеет тип ArrayBuffer[Project], Ваш для понимания desugars к mapпоэтому результат имеет тип ArrayBuffer[dom.raw.Node],

В вашем выражении соответствия шаблона вы смешиваете dom.raw.Node а также ArrayBuffer[dom.raw.Node]наименьшая верхняя граница этих двух типов Object вот почему он появляется в сообщении об ошибке.

Одним из способов решения этой проблемы было бы вернуть dom.raw.Node в каждой ветви сопоставления с образцом, например:

case ... =>
  <div>
    (for (project <- projects.items) yield <p> {project.title} </p>).toSeq
  </div>

Сейчас я могу использовать функцию рендера для решения этой проблемы.

          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>
          }

хотя это нужно добавить еще немного кода, но это работает

Надеюсь, кто-то даст более простое решение

Другие вопросы по тегам