Kotlin Json parsing MVVM

故事扮演 提交于 2019-12-11 16:59:38

问题


I'm trying to learn MVVM architecture on parse Json into a Recyclerview in MVVM using coroutines. But I'm getting error on BlogRepository class.

My Json file looks like this:

[
  {
    "id": 1,
    "name": "potter",
    "img": "https://images.example.com/potter.jpg"
},
{ …}
]

I have created data class as below:

@JsonClass(generateAdapter = true)
class ABCCharacters (

    @Json(name = "id") val char_id: Int,
    @Json(name = "name") val name: String? = null,
    @Json(name = "img") val img: String
)

Then the RestApiService as below:

interface RestApiService {

    @GET("/api")
    fun getPopularBlog(): Deferred<List<ABCCharacters>>

    companion object {

        fun createCorService(): RestApiService {

            val okHttpClient = OkHttpClient.Builder()
                .connectTimeout(1, TimeUnit.MINUTES)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .build()

            return Retrofit.Builder()
                .baseUrl("https://example.com")
                .addConverterFactory(MoshiConverterFactory.create())
                .client(okHttpClient)
                .addCallAdapterFactory(CoroutineCallAdapterFactory())
                .build().create(RestApiService::class.java)
        }
    }
}

BlogReposity.kt

class BlogRepository() {

    private var character = mutableListOf<ABCCharacters>()
    private var mutableLiveData = MutableLiveData<List<ABCCharacters>>()
    val completableJob = Job()
    private val coroutineScope = CoroutineScope(Dispatchers.IO + completableJob)

    private val thisApiCorService by lazy {
        RestApiService.createCorService()
    }

    fun getMutableLiveData():MutableLiveData<List<ABCCharacters>> {
        coroutineScope.launch {
            val request = thisApiCorService.getPopularBlog()
            withContext(Dispatchers.Main) {
                try {

                    val response = request.await()
                    val mBlogWrapper = response;
                    if (mBlogWrapper != null && mBlogWrapper.name != null) {
                        character = mBlogWrapper.name as MutableList<ABCCharacters>
                        mutableLiveData.value=character;
                    }

                } catch (e: HttpException) {
                    // Log exception //

                } catch (e: Throwable) {
                    // Log error //)
                }
            }
        }
        return mutableLiveData;
    }
}

Finally the ViewModel class

class MainViewModel() : ViewModel() {

    val characterRepository= BlogRepository()
    val allBlog: LiveData<List<ABCCharacters>> get() = characterRepository.getMutableLiveData()

    override fun onCleared() {
        super.onCleared()
        characterRepository.completableJob.cancel()
    }
}

I've done this based on https://itnext.io/kotlin-wrapping-your-head-around-livedata-mutablelivedata-coroutine-networking-and-viewmodel-b552c3a74eec Someone can guide me where am I going wrong & how to fix it?


回答1:


Your getPopularBlog() API return List<ABCCharacters> instead of ABCCharacters. So, you can't access ABCCharacters's property from your response directly. That's why name property here shows Unresolved reference.

Try below code:

if (mBlogWrapper != null && mBlogWrapper.isNotEmpty()) {
    character = mBlogWrapper as MutableList<ABCCharacters>
    mutableLiveData.value = character
}



回答2:


Your response return List but you want to check single object value (mBlogWrapper.name != null). You dont need this line on your code. In the example he checked if "response" is not a "null" and if the blog list is not null. Analize example one more time ;)

if you still have a problem with it, let me know



来源:https://stackoverflow.com/questions/58808044/kotlin-json-parsing-mvvm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!