Как отобразить результат 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>
}
хотя это нужно добавить еще немного кода, но это работает
Надеюсь, кто-то даст более простое решение