I have a kotlin function that fetches data from an api endpoint. The base api endpoint is in a constant inside the activity. It looks like so:
object AppConstants {
const val API_URL = "http://192.168.100.2:8000/api/"
}
The function is like so:
private fun thisGenreBookListJson(recyclerView: RecyclerView) {
val categoryId: String = intent.getStringExtra(CATEGORY_ID).toString()
// we get the url to list all the book genres
val genreAPiUrl = AppConstants.API_URL "books/category/$categoryId"
val thisRequest = Request.Builder().url(genreAPiUrl).build()
val client = OkHttpClient()
// enqueue makes sure the thread runs in the background
client.newCall(thisRequest).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val thisBody = response.body?.string()
val thisGson = GsonBuilder().create()
val bookList = thisGson.fromJson(thisBody, BookList::class.java)
[email protected] {
recyclerView.adapter = CategoryBookListAdapter(bookList)
}
}
override fun onFailure(call: Call, e: IOException) {
println("Failed fetching URL $e")
}
})
See the line val genreAPiUrl = "http://192.168.100.2:8000/api/books/category/$categoryId"
if left as is, it throws a com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
error. However, on debugging the app, the URL seems to be formed correctly. If I replace the $categoryId
inside this line with a category from the database, the code runs without any errors, and on debugging, it is the same as the concatenated one. On the first line of the function, removing the toString()
has no effect too.
I can't seem to find any question here similar to this one.
What could I be missing? Is it a concatenation issue? Thank you.
CodePudding user response:
You can try this approach:
val genreAPiUrl = "${AppConstants.API_URL}books/category/$categoryId"
CodePudding user response:
Expected BEGIN_OBJECT but was STRING at line 1 column 1
It means to say that your JSON might is not formatted correctly.
Gson is expecting your JSON string to begin with an object opening from
{
But the response start from
"
CodePudding user response:
The IllegalStateException
is thrown because the server returns an error instead of the expected Json (I assume some 404/40x).
Since using a valid categoryId
works, the categoryId
retrieved from the Intent
must be invalid.
However, on debugging the app, the URL seems to be formed correctly
This could have two meanings:
- when stepping through with the debugger you could verify that
categoryId
is a valid/correct id for which a book category exists in the db - when stepping through with the debugger you could verify that the URL is well-formed but you didn't verify if the
categoryId
is valid/correct
Case 1
Since your debug session shows the categoryId
is correct, the conclusion is that it's a race condition. Something must not set the Intent
parameter correctly or rather set it too late so that it's correct when you step through the debugger but not correct yet when run without attached debugger. Next step would be to use some print statements to check whether categoryId
is correct when the app runs without debugger (probably not) and then figure out what goes wrong when setting the id in the Intent
.
Case 2
In this case you need to debug the root cause and that's the id being wrong in the Intent
. Without seeing more code it's impossible to say where the id comes from and why it's not valid.