title: Kotlin handle retrofit request with coroutines
body: <p>I'm making an Android app and i'm trying to make a login. I made a basic retofit request and it works, but i want to handle the response from the server with a generic class, to show error to the user (for example email/password wrong).
  I follow this tutorial <a href="https://blog.mindorks.com/using-retrofit-with-kotlin-coroutines-in-android" rel="nofollow noreferrer">https://blog.mindorks.com/using-retrofit-with-kotlin-coroutines-in-android</a> but here he make the request in the viewModel and access to the data stored in Resource in the mainActivity (the view class). I want to access data in the viewModel to save some information in shared preferences (look the comment in the first code block), but I don't know how to do this.
  Can someone explain me how to change the code to have access to <strong>data</strong> in Resource from the ViewModel?
  Here is my viewModel:</p>
  <pre><code>class LoginViewModel(private val loginRepo: LoginRepository) : ViewModel() {
  private fun makeLogin(email: String, password: String) {
          viewModelScope.launch {
              Resource.loading(data = null)
              try {
  
                  val usr = User(email, password)
                  Resource.success(data = loginRepo.makeLogin(usr))
                  // HERE I WANT TO ACCESS TO DATA TO STORE SOME INFORMATION IN SHARED PREFERENCES
              } catch (ex: Exception) {
                  Resource.error(data = null, message = ex.message ?: &quot;Error occured!&quot;)
              }
  }
  </code></pre>
  <p>here is the resource class:</p>
  <pre><code>data class Resource&lt;out T&gt;(val status: Status, val data: T?, val message: String?) {
      companion object {
          fun &lt;T&gt; success(data: T): Resource&lt;T&gt; = Resource(status = Status.SUCCESS, data = data, message = null)
  
          fun &lt;T&gt; error(data: T?, message: String): Resource&lt;T&gt; =
              Resource(status = Status.ERROR, data = data, message = message)
  
          fun &lt;T&gt; loading(data: T?): Resource&lt;T&gt; = Resource(status = Status.LOADING, data = data, message = null)
      }
  }
  </code></pre>
  <p>here is the Repository:</p>
  <pre><code>class LoginRepository(private val apiHelper: ApiHelper) {
      suspend fun makeLogin(usr: User) = apiHelper.makeLogin(usr)
  }
  </code></pre>
  <p>The return type of apiHelper.makeLogin(usr) is:</p>
  <pre><code>
  @JsonClass(generateAdapter = true)
  data class LoginResponse(
      val token: String,
      val expiration: String,
      val id : Int,
      val role: Int)
  </code></pre>
  <p><strong>The viewModel of the tutorial</strong>:</p>
  <pre><code>class MainViewModel(private val mainRepository: MainRepository) : ViewModel() {
  
      fun getUsers() = liveData(Dispatchers.IO) {
          emit(Resource.loading(data = null))
          try {
              emit(Resource.success(data = mainRepository.getUsers()))
          } catch (exception: Exception) {
              emit(Resource.error(data = null, message = exception.message ?: &quot;Error Occurred!&quot;))
          }
      }
  }
  </code></pre>
  <p><strong>In the tutorial</strong> he access the data stored in Resource in the main activity like this:</p>
  <pre><code>viewModel.getUsers().observe(this, Observer {
              it?.let { resource -&gt;
                  when (resource.status) {
                      SUCCESS -&gt; {
                          recyclerView.visibility = View.VISIBLE
                          progressBar.visibility = View.GONE
                          resource.data?.let { users -&gt; retrieveList(users) }
                      }
                      ERROR -&gt; {
                          recyclerView.visibility = View.VISIBLE
                          progressBar.visibility = View.GONE
                          Toast.makeText(this, it.message, Toast.LENGTH_LONG).show()
                      }
                      LOADING -&gt; {
                          progressBar.visibility = View.VISIBLE
                          recyclerView.visibility = View.GONE
                      }
                  }
              }
          })
  </code></pre>