BookLog App Schema Sync to Atlas and Error Handling

Henna Singh
3 min readFeb 26, 2022

--

#BuildTogether Day 20/100

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())
AddAuthor Fragment

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”

Author Collection on Cloud

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… 👋🏽

--

--

Henna Singh
Henna Singh

Written by Henna Singh

Technical Speaker and an aspiring writer with avid addiction to gadgets, meet-up groups, and paper crafts. Currently doing Full Stack Diploma at Code Institute

No responses yet