title: how to use suspend properly over deferred in kotlin coroutines?
body: <p>I am developing news app and I have implemented kotlin coroutines since Retrofit 2.6.0 has been released with support for suspend functions. I have implemented suspend function over deferred function and <a href="https://proandroiddev.com/suspend-what-youre-doing-retrofit-has-now-coroutines-support-c65bd09ba067" rel="nofollow noreferrer">followed this tutorial</a> but I am getting empty data I want to know where I am making mistake? where I have to make correction to show data correctly. <code>on stacktrace getting following exception kotlinx.coroutines.JobCancellationException: Job was cancelled;</code> job=JobImpl{Cancelling}@677a578</p>
  
  <p>I have define my ending point followingly in SportInterface.kt</p>
  
  <pre><code>@GET("v2/top-headlines?country=us&amp;apiKey=da331087e3f3462bb534b3b0917cbee9")
       suspend fun getNewsAsync(): SportNewsResponse
  </code></pre>
  
  <p>previously it was below</p>
  
  <pre><code> @GET("v2/top-headlines?country=us&amp;apiKey=da331087e3f3462bb534b3b0917cbee9")
       fun getNewsAsync(): Deferred&lt;SportNewsResponse&gt;
  </code></pre>
  
  <p>and getting result in NewsRepository following way.</p>
  
  <pre><code>interface NewsRepository {
      // Suspend is used to await the result from Deferred
     suspend fun getNewsList(): UseCaseResult&lt;List&lt;Article&gt;&gt;
  }
  
  
  @Suppress("UNCHECKED_CAST")
  class NewsRepositoryImpl(private val sportsNewsApi: SportNewsInterface) : NewsRepository {
      override suspend fun getNewsList(): UseCaseResult&lt;List&lt;Article&gt;&gt; {
  
          return try {
              val result = sportsNewsApi.getNewsAsync().articles
              UseCaseResult.Success(result)
          } catch (ex: Exception) {
              UseCaseResult.Error(ex)
          }
      }
  }
  </code></pre>
  
  <p>and below my MainViewModel.kt</p>
  
  <pre><code>@Suppress("UNCHECKED_CAST")
  class MainViewModel(val newsRepository: NewsRepository) : ViewModel(), CoroutineScope {
      // Coroutine's background job
      val job = Job()
      // Define default thread for Coroutine as Main and add job
      override val coroutineContext: CoroutineContext = Dispatchers.Main + job
  
      val showLoading = MutableLiveData&lt;Boolean&gt;()
      val sportList = MutableLiveData &lt;List&lt;Article&gt;&gt;()
      val showError = SingleLiveEvent&lt;String&gt;()
  
      fun loadNews() {
          // Show progressBar during the operation on the MAIN (default) thread
          showLoading.value = true
          // launch the Coroutine
          launch {
              // Switching from MAIN to IO thread for API operation
              // Update our data list with the new one from API
              val result = withContext(Dispatchers.IO) {
                  newsRepository?.getNewsList()
              }
              // Hide progressBar once the operation is done on the MAIN (default) thread
              showLoading.value = false
              when (result) {
  
                  is UseCaseResult.Success&lt;*&gt; -&gt; {
                      sportList.value = result.data as List&lt;Article&gt;
                  }
                  is Error -&gt; showError.value = result.message
              }
          }
      }
  
      override fun onCleared() {
          super.onCleared()
          // Clear our job when the linked activity is destroyed to avoid memory leaks
          job.cancel()
      }
  }
  </code></pre>
  
  <p>below my SportNewsResponse.kt data class</p>
  
  <pre><code>data class SportNewsResponse(
      val articles: List&lt;Article&gt;,
      val status: String,
      val totalResults: Int
  )
  </code></pre>
  
  <p>below Article.kt</p>
  
  <pre><code>@Entity(tableName = "news_table")
  data class Article(@ColumnInfo(name = "author")val author: String,
                     val content: String,
                     val description: String,
                     val publishedAt: String,
                     val source: Source,
                     val title: String,
                     val url: String,
                     val urlToImage: String
  )
  </code></pre>
  
  <p>below my jsonResponse from server</p>
  
  <pre><code>{
      "status": "ok",
      "totalResults": 38,
      "articles": [
          {
              "source": {
                  "id": "cnbc",
                  "name": "CNBC"
              },
              "author": "Holly Ellyatt",
              "title": "Russia is now not the only pressing issue that NATO has to deal with - CNBC",
              "description": "Heads of state and government are meeting in the U.K. this week for the 70th anniversary of the military alliance NATO.",
              "url": "https://www.cnbc.com/2019/12/02/nato-summit-alliance-has-more-pressing-issues-than-russia-now.html",
              "urlToImage": "https://image.cnbcfm.com/api/v1/image/106272467-1575218599700gettyimages-997112494.jpeg?v=1575218712",
              "publishedAt": "2019-12-02T07:39:00Z",
              "content": "US president Donald Trump is seen during his press conference at the 2018 NATO Summit in Brussels, Belgium on July 12, 2018.\r\nAs heads of state and government meet in the U.K. this week for the 70th anniversary of the military alliance NATO, discussions are l… [+8623 chars]"
          },
          {
              "source": {
                  "id": null,
                  "name": "Chron.com"
              },
              "author": "Aaron Wilson",
              "title": "Bill O'Brien gets game ball from Deshaun Watson after Texans' win over Patriots - Chron",
              "description": "In an emotional moment, Texans coach Bill O'Brien was presented with the game ball by quarterback Deshaun Watson following a pivotal win over the New England Patriots.",
              "url": "https://www.chron.com/sports/texans/article/Bill-O-Brien-Deshaun-Watson-Texans-Patriots-14874678.php",
              "urlToImage": "https://s.hdnux.com/photos/01/07/23/50/18692664/3/rawImage.jpg",
              "publishedAt": "2019-12-02T06:16:00Z",
              "content": "&lt;ul&gt;&lt;li&gt;Houston Texans head coach Bill O'Brien on the sidelines during the fourth quarter of an NFL game against the New England Patriots at NRG Stadium Sunday, Dec. 1, 2019, in Houston.\r\nHouston Texans head coach Bill O'Brien on the sidelines during the four… [+1583 chars]"
  
  
          }
      ]
  }
  </code></pre>
  
  <p>below my retrofit implementation appmodules.kt</p>
  
  <pre><code>const val BASE_URL = "https://newsapi.org/"
  
  val appModules = module {
      // The Retrofit service using our custom HTTP client instance as a singleton
      single {
          createWebService&lt;SportNewsInterface&gt;(
              okHttpClient = createHttpClient(),
              factory = RxJava2CallAdapterFactory.create(),
              baseUrl = BASE_URL
          )
      }
      // Tells Koin how to create an instance of CatRepository
      factory&lt;NewsRepository&gt; { (NewsRepositoryImpl(sportsNewsApi = get())) }
      // Specific viewModel pattern to tell Koin how to build MainViewModel
      viewModel { MainViewModel (newsRepository = get ())  }
  }
  
  /* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
  fun createHttpClient(): OkHttpClient {
      val client = OkHttpClient.Builder()
      client.readTimeout(5 * 60, TimeUnit.SECONDS)
      return client.addInterceptor {
          val original = it.request()
          val requestBuilder = original.newBuilder()
          requestBuilder.header("Content-Type", "application/json")
          val request = requestBuilder.method(original.method, original.body).build()
          return@addInterceptor it.proceed(request)
      }.build()
  }
  
  /* function to build our Retrofit service */
  inline fun &lt;reified T&gt; createWebService(
      okHttpClient: OkHttpClient,
      factory: CallAdapter.Factory, baseUrl: String
  ): T {
      val retrofit = Retrofit.Builder()
          .baseUrl(baseUrl)
          .addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
          .addCallAdapterFactory(CoroutineCallAdapterFactory())
          .addCallAdapterFactory(factory)
          .client(okHttpClient)
          .build()
      return retrofit.create(T::class.java)
  
  }
  </code></pre>
  
  <p>below  TopHeadlinesFragment.kt</p>
  
  <pre><code>class TopHeadlinesFragment : Fragment() {
  
      private val viewModel by viewModel&lt;MainViewModel&gt;()
      private lateinit var topHeadlinesAdapter: TopHeadlinesAdapter
     // private   val newsRepository: NewsRepository by inject()
  
  
  
      //3
      override fun onCreateView(
          inflater: LayoutInflater,
          container: ViewGroup?,
          savedInstanceState: Bundle?
      ): View? {
          val view = inflater.inflate(
              R.layout.fragment_top_headlines
              , container, false
          )
  
  
          val recyclerView = view.findViewById(R.id.recyclerView) as RecyclerView
          val pb = view.findViewById(R.id.pb) as ProgressBar
          topHeadlinesAdapter = TopHeadlinesAdapter(recyclerView.context)
          recyclerView.layoutManager = LinearLayoutManager(context)
          recyclerView.adapter = topHeadlinesAdapter
          initViewModel()
  
          return view
      }
  
      private fun initViewModel() {
          viewModel?.sportList?.observe(this, Observer { newList -&gt;
              topHeadlinesAdapter.updateData(newList)
          })
  
          viewModel?.showLoading?.observe(this, Observer { showLoading -&gt;
              pb.visibility = if (showLoading) View.VISIBLE else View.GONE
          })
  
          viewModel?.showError?.observe(this, Observer { showError -&gt;
              (showError)
          })
  
          viewModel?.loadNews()
      }
  }
  </code></pre>