https://kotlinlang.org logo
#android
Title
# android
t

T

05/28/2020, 12:41 PM
I want to return the string form of the Json response. The error I get is "Expected a string but was BEGIN_OBJECT at path$"
Copy code
private const val BASE_URL = "<https://newsapi.org/v2/>"
private const val API_KEY = "1234"

private val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .build()

private val retrofit = Retrofit.Builder()
    .addConverterFactory(MoshiConverterFactory.create())
    .baseUrl(BASE_URL)
    .build()

interface NewsApiService {
    @GET("top-headlines?country=us&apiKey=${API_KEY}")
    fun getProperties():
            Call<String>
}

object NewsApi {
    val retrofitService : NewsApiService by lazy {
        retrofit.create(NewsApiService::class.java) }
}
Copy code
class NewsViewModel : ViewModel() {

    // The internal MutableLiveData String that stores the most recent response
    private val _response = MutableLiveData<String>()

    // The external immutable LiveData for the response String
    val response: LiveData<String>
        get() = _response

    /**
     * Call getNewsData() on init so we can display status immediately.
     */
    init {
        getNewsData()
    }

    /**
     * Sets the value of the status LiveData to the News API status.
     */
    private fun getNewsData() {

        _response.value = NewsApi.retrofitService.getProperties().enqueue(
            object: Callback<String> {
                override fun onFailure(call: Call<String>, t: Throwable){
                    _response.value = "Failure: " + t.message
                }

                override fun onResponse(call: Call<String>, response: Response<String>) {
                   _response.value = response.body()
                }
            }).toString()
    }
}
This is how the json response look like
a

allan.conda

05/28/2020, 12:56 PM
you have to write your own converter I think
j

jw

05/28/2020, 1:03 PM
yep. make an annotation
@Json
, annotate the endpoint with
@Json
and have its body type as
String
, in a custom converter match on both the
type == String::class.java
and the annotations array contains an instance of
Json::class.java
and then just call
ResponseBody.string()
and return it.
Of course, nothing guarantees that the return format from the endpoint is actually JSON. You can also just install the scalars converter that Retrofit ships and use
String
and it'll do exactly the same thing
Or you can just declare
ResponseBody
as your type and call
string()
yourself
t

T

05/28/2020, 3:41 PM
Thanks @jw I actually added scalar converter to my gradle build and the magic happened.
What is the difference between the MoshiConverterFactory and ScalarConverterFactory
How do I return the List of array in articles from the sample Json response?
77 Views