ashmelev
08/11/2022, 4:32 PMdataUpdateOnEdit = true
mode I get a (rather lengthy) Uncaught exception...
in the browser console which seems to indicate an issue when setting data:
<redacted>....refreshActiveData@http://localhost:8080/web/main.bundle.js:2:1490426\n_setDataActual@http://localhost:8080/web/main.bundle.js:2:1485115\n2995/setData/<@http://localhost:8080/web/main.bundle.js:2:1484530\nsetData@http://localhost:8080/web/main.bundle.js:2:1484442.....<redacted>
The data source for the Tabulator is declared as:
val organizations: ObservableList<OrganizationExch> = observableListOf()
and OrganizationExch
is declared as
@Serializable
data class OrganizationExch(@Id var extId: String,
var name: String,
var description: String? = null,
var webUrl: String? = null,
var imageUrl: String? = null,
var theme: String? = null,
var createdAt: OffsetDateTime? = null,
var updatedAt: OffsetDateTime? = null)
[NOTE: I am trying to edit webUrl
in my tests]
The data originates from a List
on the KVision back-end (SpringBoot) and I convert it into a MutableList<OrganizationExch>
before synch (probably unnecessary):
organizations.syncWithList(organizationService.getOrganizations().toMutableList())
I am clearly missing something..... can you help?Robert Jaros
08/11/2022, 4:33 PMashmelev
08/11/2022, 4:34 PMkotlin.js.compiler=ir
IR compilerRobert Jaros
08/11/2022, 4:35 PMserializer = serializer()
?ashmelev
08/11/2022, 4:36 PMashmelev
08/11/2022, 4:37 PMdsl
builder (which was causing the same/similar exception)ashmelev
08/11/2022, 4:37 PMRobert Jaros
08/11/2022, 4:39 PM@JsExport
on your model data class. Do you see your data without it? :-)ashmelev
08/11/2022, 4:39 PMserializer
was defined:
orgTable = Tabulator(
OrganizationModel.organizations,
dataUpdateOnEdit = false,
options = TabulatorOptions(
layout = Layout.FITCOLUMNS,
columns = listOf(
ColumnDefinition(<http://I18n.tr|I18n.tr>("extId"), "extId", visible = false),
ColumnDefinition(<http://I18n.tr|I18n.tr>("Name"), "name", editor = Editor.INPUT, cellEdited = { cellEdited(it) }),
ColumnDefinition(<http://I18n.tr|I18n.tr>("Description"), "description", editor = Editor.INPUT, cellEdited = { cellEdited(it) }, width = "350"),
ColumnDefinition(<http://I18n.tr|I18n.tr>("Web Url"), "webUrl", editor = Editor.INPUT, cellEdited = { cellEdited(it) }, width = "200"),
ColumnDefinition(<http://I18n.tr|I18n.tr>("Logo Image Url"), "imageUrl", editor = Editor.INPUT, cellEdited = { cellEdited(it) }, width = "200"),
ColumnDefinition(<http://I18n.tr|I18n.tr>("Theme"), "theme", editor = Editor.INPUT, cellEdited = { cellEdited(it) }, width = "100"),
ColumnDefinition(<http://I18n.tr|I18n.tr>("Created At"), "createdAt", width = "175"),
ColumnDefinition(<http://I18n.tr|I18n.tr>("Updated At"), "updatedAt", width = "175")
),
index = "extId",
pagination = true,
paginationMode = PaginationMode.LOCAL,
paginationSize = 10,
autoResize = true
), types = setOf(TableType.BORDERED, TableType.HOVER, TableType.STRIPED), serializer = serializer()
).apply {
height = 100.perc
}
Robert Jaros
08/11/2022, 4:39 PMashmelev
08/11/2022, 4:39 PMserializer = serializer
above - just added that 2 seconds agoashmelev
08/11/2022, 4:40 PM.apply {
pre-existedRobert Jaros
08/11/2022, 4:46 PMcellEdited(...)
function doing?ashmelev
08/11/2022, 4:47 PMconsole.log()
ashmelev
08/11/2022, 4:47 PMprivate fun cellEdited(editedCell: io.kvision.tabulator.js.Tabulator.CellComponent) {
try {
if (editedCell.isEdited()) {
editedCell.getRow().getIndex().let {
val extId = (it.asDynamic() as String)
console.log("cellEdited index $extId")
OrganizationModel.editRow(
extId = extId,
fieldName = editedCell.getField(),
oldValue = editedCell.getOldValue(),
newValue = editedCell.getValue()
)
}
}
} catch (e: Exception) {
console.error("cellEdited threw ${e::class.simpleName}: ${e.message}")
}
}
ashmelev
08/11/2022, 4:48 PMfun editRow(extId: String, fieldName: String, oldValue: Any?, newValue: Any?) {
console.log("OrganizationModel.editRow(extId=$extId, fieldName=$fieldName, oldValue=$oldValue, newValue=$newValue)")
organizations.firstOrNull { it.extId == extId }?.let { orgExch ->
console.log("OrganizationModel.editRow(orgExch=$orgExch)")
}
}
ashmelev
08/11/2022, 4:48 PMdataUpdateOnEdit = false
then all the log dump runs w/o error or exceptionashmelev
08/11/2022, 4:49 PMdataUpdateOnEdit = true
then the console logs as before and the exception is thrown after the event handler completesRobert Jaros
08/11/2022, 4:53 PMashmelev
08/11/2022, 4:54 PMavaVersion=1.8
#Plugins
systemProp.kotlinVersion=1.7.10
serializationVersion=1.3.3
systemProp.dependencyManagementPluginVersion=1.0.12.RELEASE
systemProp.springBootVersion=2.7.0
#Dependencies
systemProp.kvisionVersion=5.13.1
coroutinesVersion=1.6.4
systemProp.keycloakVersion=12.0.3
systemProp.jibVersion=3.2.1
systemProp.micrometerVersion=1.8.1
systemProp.jacksonVersion=2.13.3
systemProp.apacheCommonsIoVersion=1.3.2
systemProp.hazelcastVersion=5.1.2
systemProp.awsSdkVersion=2.17.42
systemProp.okHttpVersion=4.10.0
systemProp.retrofitVersion=2.9.0
kotlin.mpp.stability.nowarn=true
kotlin.js.compiler=ir
org.gradle.jvmargs=-Xmx2g
ashmelev
08/11/2022, 4:54 PM5.13.1
Robert Jaros
08/11/2022, 4:55 PMkvision-tabulator
module (not kvision-tabulator4
) ?ashmelev
08/11/2022, 4:55 PMashmelev
08/11/2022, 4:56 PMimplementation("io.kvision:kvision-tabulator:$kvisionVersion")
Robert Jaros
08/11/2022, 4:58 PMdataUpdateOnEdit = true
. But this is in plain frontend project. I'll try once again with the fullstack project.ashmelev
08/11/2022, 4:59 PMashmelev
08/11/2022, 5:00 PMRobert Jaros
08/11/2022, 5:06 PMashmelev
08/11/2022, 5:07 PMresources/public
directory inside the SpringBoot BackEnd. There are two reasons for this:
1.) So that I can use SpringBoot's SpringSecurity/ResourceServer and KeyCloak to secure the entire application, and
2.) So that I can use a Google Jib Gradle task to package the entire thing to a Docker container for production deployment to Kubernetes
Right now I am testing locally, so I am not performing all that packaging (i.e. I am running things like your full-stack SpringBoot example), but there is an outside possibility that something is unique to my setup and causing the problem...Robert Jaros
08/11/2022, 5:09 PMclass App : Application() {
val organizations: ObservableList<OrganizationExch> =
observableListOf(
OrganizationExch("1", "111", createdAt = Date(), updatedAt = Date()),
OrganizationExch("2", "222", createdAt = Date(), updatedAt = Date())
)
fun cellEdited(cell: io.kvision.tabulator.js.Tabulator.CellComponent) {
}
override fun start(state: Map<String, Any>) {
I18n.manager =
DefaultI18nManager(
mapOf(
"en" to io.kvision.require("i18n/messages-en.json"),
"pl" to io.kvision.require("i18n/messages-pl.json")
)
)
root("kvapp") {
tabulator(
organizations,
serializer = serializer(),
dataUpdateOnEdit = true,
options = TabulatorOptions(
layout = Layout.FITCOLUMNS,
columns = listOf(
ColumnDefinition(<http://I18n.tr|I18n.tr>("extId"), "extId", visible = false),
ColumnDefinition(
<http://I18n.tr|I18n.tr>("Name"),
"name",
editor = Editor.INPUT,
cellEdited = { cellEdited(it) }),
ColumnDefinition(
<http://I18n.tr|I18n.tr>("Description"),
"description",
editor = Editor.INPUT,
cellEdited = { cellEdited(it) },
width = "350"
),
ColumnDefinition(
<http://I18n.tr|I18n.tr>("Web Url"),
"webUrl",
editor = Editor.INPUT,
cellEdited = { cellEdited(it) },
width = "200"
),
ColumnDefinition(
<http://I18n.tr|I18n.tr>("Logo Image Url"),
"imageUrl",
editor = Editor.INPUT,
cellEdited = { cellEdited(it) },
width = "200"
),
ColumnDefinition(
<http://I18n.tr|I18n.tr>("Theme"),
"theme",
editor = Editor.INPUT,
cellEdited = { cellEdited(it) },
width = "100"
),
ColumnDefinition(<http://I18n.tr|I18n.tr>("Created At"), "createdAt", width = "175"),
ColumnDefinition(<http://I18n.tr|I18n.tr>("Updated At"), "updatedAt", width = "175")
),
index = "extId",
pagination = true,
paginationMode = PaginationMode.LOCAL,
paginationSize = 10,
autoResize = true
), types = setOf(TableType.BORDERED, TableType.HOVER, TableType.STRIPED)
).apply {
height = 100.perc
}
}
}
}
Robert Jaros
08/11/2022, 5:09 PMOrganizationExch
in the common module just like youashmelev
08/11/2022, 5:11 PMRobert Jaros
08/11/2022, 5:15 PMashmelev
08/11/2022, 5:16 PMashmelev
08/11/2022, 5:16 PMashmelev
08/11/2022, 5:17 PMRobert Jaros
08/11/2022, 5:19 PMtabulator()
and you have constructor Tabulator()
.ashmelev
08/11/2022, 5:19 PMdsl
versionRobert Jaros
08/11/2022, 5:20 PMcreate
functions defined.Robert Jaros
08/11/2022, 5:20 PMashmelev
08/11/2022, 5:20 PMRobert Jaros
08/11/2022, 5:21 PMTabulator.create()
works fineRobert Jaros
08/11/2022, 5:24 PMkClass
as well (kClass = OrganizationExch::class
)ashmelev
08/11/2022, 5:30 PMashmelev
08/11/2022, 5:32 PMcellEdit
event is firing before the Tabulator has a chance to update the underlying List. How can I capture the change event after the record in the List is updated? I need to message it back to the underlying store....Robert Jaros
08/11/2022, 5:35 PMashmelev
08/11/2022, 5:38 PMRobert Jaros
08/11/2022, 5:39 PMsubscribe()
.ashmelev
08/11/2022, 5:39 PMRobert Jaros
08/11/2022, 5:39 PMashmelev
08/11/2022, 5:40 PMcellEdited
handler then...
Thank you for the help!Robert Jaros
08/11/2022, 5:41 PMcellEdited
is probably the best in this case.Robert Jaros
08/11/2022, 5:42 PMashmelev
08/11/2022, 5:42 PM