BookLog App Schema Sync to Atlas and Error Handling
Today was a fun day, good breakfast, hustling in cold and wind, some sightseeing, Movi watching (Constantine), and then coding.
As I mentioned yesterday, I was struggling to make the app work using the Asynchronous method of opening Realm, so today I tried opening it synchronously and it worked…
My bottom navigation view is visible with the home page to BookList Fragment, and I tried opening AddAuthor view and got hit by an interesting error:
FATAL EXCEPTION: main
Process: com.geek.booklog, PID: 25538
io.realm.exceptions.RealmException: Async transaction failed
Caused by: io.realm.exceptions.RealmException: 'Author' has a primary key, use 'createObject(Class<E>, Object)' instead.
This was a great learning today, which I didn’t know. My Author class and code to add author in the fragment is as below:
open class Author(
@PrimaryKey
var _id: ObjectId = ObjectId(),
@Required
var name: String = "",
@LinkingObjects("authors")
val books: RealmResults<Book>? = null
): RealmObject() { }private fun createAuthorObject(authorName: String) {
realmClass.executeTransactionAsync{ it ->
val author = it.createObject(Author::class.java)
//configure the instance
author.name = authorName
}
}
I edited the following line of code to accept the primary key and I ran the app.
val author = it.createObject(Author::class.java, ObjectId())
As a result, JK Rowling got added to the cloud and my schema also got automatically populated to Atlas
Collections can be viewed by going to the Atlas Tab and “Browse Collections”
I was missing implementation of success and error result of adding author... My UI does not change after Author is successfully added. So I updated the method signature to take onSuccess
and onError
calls as well
private fun createAuthorObject(authorName: String) {
realmClass.executeTransactionAsync({
val author = it.createObject(Author::class.java, ObjectId())
//configure the instance
author.name = authorName
}, {
Timber.d("Successfully Added")
Toast.makeText(context, "Author successfully added", Toast.LENGTH_LONG).show()
}, {
Timber.e("Error adding Author %s",it.localizedMessage)
Toast.makeText(context, "Author cannot be added, Try again!", Toast.LENGTH_LONG).show()
})
}
If you would like to understand the above method call, take a look at Asynchronous API in Realm Docs.
Also, I was able to test if typecast to CharSequence
will work, it turns out it does not as I get the following error on running the app and trying to input Author.
val arrayAuthor = authorList.toArray() as Array<CharSequence>io.realm.exceptions.RealmException: Async transaction failedCaused by: java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.CharSequence[]
I will continue this tomorrow… 👋🏽