In my code, I execute the below block at the init
:
package main
import (
"syscall/js"
)
type object map[string]interface{}
var Window = js.Global()
type DataBase struct {
Data, Transactions, ObjectStore, Request js.Value
Upgrade js.Func
}
var DB DataBase // All the struct fields are initialized with their zero value
func init() {
DB.init("dataSet", "table")
}
Where the func DB.init is:
package main
import (
"fmt"
"syscall/js"
)
func (db *DataBase) init(dataSet, table string) {
var Ok, Err js.Func
db.Request = Window.Get("indexedDB").Call("open", dataSet, 1)
db.Upgrade = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
defer db.Upgrade.Release()
db.Data = this.Get("result")
Store := db.Data.Call("createObjectStore", table, map[string]interface{}{"keyPath": "id"})
Store.Call("add", map[string]interface{}{"id": "00-03", "name": "Karam", "age": 19, "email": "kenny@planet.org"})
Window.Call("alert", "First record posted.")
return nil
})
Ok = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
db.Data = this.Get("result")
stores := []string{table}
objectStore := make([]interface{}, len(stores))
for i, v := range stores {
objectStore[i] = v
}
db.Transactions = db.Data.Call("transaction", objectStore, "readwrite").Call("objectStore", table)
db.ObjectStore = db.Data.Call("transaction", objectStore).Call("objectStore", table)
Window.Call("alert", "Database is ready!")
return nil
})
Err = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
Window.Call("alert", "sorry, could not initiate DB")
return nil
})
db.Request.Set("onupgradeneeded", db.Upgrade)
db.Request.Set("onsuccess", Ok)
db.Request.Set("onerror", Err)
}
The above is using indexedDB API, where db.Upgrade
is run only once at the first time the application run (or if the DB had been removed, or new firsion had been assigned)
Then we have the Ok
is run first thing in the app everytime the app is run (after upgrade)
I assume with the code above the variable db.Transactions
should be existing and attached to the DB
as far as the app is running, and I should recall it with any method attached to the struct.
But, when I call (at a later stage) the function Add
, that is:
func (db *DataBase) Add(table string, usr map[string]interface{}) {
fmt.Println(usr)
var Ok, Err js.Func
fmt.Println(table)
stores := []string{table} // to solve unexpected literal 'employee', expecting method or interface name
objectStore := make([]interface{}, len(stores))
for i, v := range stores {
objectStore[i] = v
}
// db.Transactions = db.Data.Call("transaction", objectStore, "readwrite").Call("objectStore", table)
request := db.Transactions.Call("add", usr)
Ok = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
defer Ok.Release()
Window.Call("alert", "user added.")
return nil
})
request.Set("onsuccess", Ok)
Err = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
defer Err.Release()
Window.Call("alert", "sorry, could not add user//.")
return nil
})
request.Set("onerror", Err)
}
I get an error that the db.Transactions
that is:
panic: JavaScript error: Failed to execute 'add' on 'IDBObjectStore': The transaction has finished.
But if I redefined it in my code of the function Add
, i.e. uncometting the line:
// db.Transactions = db.Data.Call("transaction", objectStore, "readwrite").Call("objectStore", table)
Then everything is run smoothly!
Any thought?