0

Guess, I'm already baffled with what I'm doing, so I'm reaching out to the community.

I have the following:

UserModel

data class UserModel(
  val id: String,
  val name: String
){}

UserService

@Headers("Accept: application/json")
@POST("register")
fun doRegisterUserTest(
    @Query("user_id") userName: String,
    @Query("password") passWord: String
): Deferred<UserModel>

UserRepository

fun test(username: String, password: String): List<UserModel>{
   Network.createNetworkRequest().create(UserService::class.java).doRegisterUserTest(username, password)
   val x: UserService by lazy {Network.createNetworkRequest().create(UserService::class.java)}
   val y = x.doRegisterUserTest(username, password)
   return y
}

UserViewModel

private val _result = MutableLiveData<List<UserModel>>()
val result: LiveData<List<UserModel>> = _result

fun onRegister(username: String, password: String) {
    viewModelScope.launch {
        // connect to api server
        //_registrationStatus.value = RegistrationStatus.LOADING
        try {
            _result.value = userRepository.test(username, password)
            ....
        }
    }
 }

Network Client

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

/**
 * Main entry point for dto access. Call like `Network.devbytes.getPlaylist()`
 */
object Network {

    fun createNetworkRequest(): Retrofit {
        // Configure retrofit to parse JSON and use coroutines
        val retrofit = Retrofit.Builder()
            .baseUrl("http://10.0.2.2:8081/api/")
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .addCallAdapterFactory(CoroutineCallAdapterFactory())
            .build()

        return retrofit
    }
}

In my api, the above (in ideal scenario) will yield the following:

{
    "user": [
        {
            "user_sys_id": 0,
            "name": "Blah blah",
        }
    ]
}

I want to read the values from _result.value = userRepository.test(username, password), I presume that test function will return a List> but I don't know how to access the members.

How can I check _result for the values of user_sys_id and name?

How come I'm getting the following (if I convert the response straight to a List)

Unable to create call adapter for Xmodel for method UserService.doRegisterUserTest

Am I missing something? Likewise, is it fine to do a Retrofit Call if you were already using Coroutines?

From this Unable to create call adapter for retrofit2.Response<...>, it seems that the function should be suspended, but if I do that I would get a warning

Redundant suspend modifier

PS. Although, if I follow repository pattern, I'm able to see that results where written on a local database the values retrieved from the API, however, I don't think that is correct to store data that aren't supposed to be stored in the first place, say for eg. in a Registration, if the registration fails you just want to read the error message directly from the response

mirageservo
  • 2,387
  • 4
  • 22
  • 31
  • First I would do some changes... your repo really is a datasource, so create a NetworkDataSource with your method test() and here use a try { } catch(ex: Exception). You could return a wrapper sealed class Result with state Success(yourData) or Error(ex). try { val yourData = retrofit.getData() Result.Success(yourData) } catch(ex) { Result.Error(ex)}. This method is suspend, in the repository a suspend test with the flow, only fetch data from datasource and return the result. In the viewmodel launch Dispatchers.IO, and then if (result is Result.Success) update your livedata – Manuel Mato Oct 22 '20 at 10:24
  • @ManuelMato 1.) So I have to store the api response to the repository first and retrieve the values from the database, wouldn't it be a waste? 2.) Is it okay to call Dispatchers.IO from a ViewModel, well from an code architecture perspective? – mirageservo Oct 22 '20 at 10:35
  • I think is not a waste because the responsability of the Repository is to do the data flow, for example: 1. I fetch data from database, if is empty, 2. then i fetch data from network, 3. Save data in database, and 4. return to 1, fetch data from database. The responsability of repository is not to know how to connect with a api, database, etc. only the flow. So the database implementation knows how to access to the data, for example connect with an api rest, connect with a database (knows the implementation: Realm, SQLite, ...), connect with a cache, etc. – Manuel Mato Oct 22 '20 at 10:54

0 Answers0