I’m having problems getting data from the Facebook API inside a varaiable. In my main activity I call viewModel.getFeed()
. The logger returns null, but OkHttp returns the response I want. How can I populate the list with this response data?
FacebookAPIService
interface FacebookAPIService {
// Get all the english movies in given year
@GET("USER_ID/feed?access_token=ACCESS_TOKEN")
fun getUserFeed(): Call<NewsItemData>
}
FacebookAPI
class FacebookAPI {
companion object {
private const val baseUrl = "https://graph.facebook.com/v5.0/"
/**
* @return [FacebookAPIService] The service class off the retrofit client
*/
fun createApi(): FacebookAPIService {
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.build()
// Create retrofit instance
val facebookApi = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
// Return the retrofit FacebookAPIService
return facebookApi.create(FacebookAPIService::class.java)
}
}
}
NewsRepository
class NewsRepository(context: Context) {
private val facebookApi: FacebookAPIService = FacebookAPI.createApi()
fun getUserFeed() = facebookApi.getUserFeed()
...
MainActivityViewModel
class MainActivityViewModel(application: Application) : AndroidViewModel(application) {
private val newsItemsRepository = NewsRepository(application.applicationContext)
val newsItems = MutableLiveData<List<NewsItem>>()
private fun getFeed() {
newsItemsRepository.getUserFeed().enqueue(object : Callback<NewsItemData?> {
override fun onResponse(call: Call<NewsItemData?>, response: Response<NewsItemData?>) {
if (response.isSuccessful) {
newsItems.value = response.body()!!.results
Log.d("response", newsItems.value.toString())
} else {
error.value = "An error has occurred: ${response.errorBody().toString()}"
Log.e("response", response.toString())
}
}
override fun onFailure(call: Call<NewsItemData?>, t: Throwable) {
error.value = t.message
}
})
}
}
NewsItem
@Parcelize
@Entity(tableName = "news_item")
data class NewsItem(
@SerializedName("message") var message: String,
@SerializedName("story") var story: String,
@PrimaryKey(autoGenerate = true) val id: Long? = null
) : Parcelable
NewsItemData
class NewsItemData {
var results: List<NewsItem>? = null
}
To give some more background my response looks something like this:
{
"data": [
...
{
"created_time": "some timestamp",
"id": "some id"
},
{
"message": "some messge",
"created_time": "some timestamp",
"id": "some id"
}
...
],
"paging": {
...
}
}
2
Answers
This my code for response parse json
Hope this help
The problem here is that you have to add a
@SerializedName
to the NewsItemDataresults
field.NewsItemData
Otherwise the JSON array won’t be correctly mapped to a list as you intended.