title: Handling screen rotation without losing data with viewModel - Android
body: <p>I have one activity with unspecified orientation and there is one fragment attached to that activity that has different layouts for portrait and landscape mode and on that fragment, multiple API calls on a conditional basis, my problem is that when the screen rotates all data was lost and there is a lot of data on that fragment by which I don't want to save each data on saveInstance method. I tried <code>android:configChanges=&quot;keyboardHidden|orientation|screenSize&quot;</code>, but this didn't solve my problem. I want to handle this problem using viewModel. Please help, Thanks in advance.
  Here is my code</p>
  <p>Repository</p>
  <pre><code>class GetDataRepository {
  val TAG = GetDataRepository::class.java.canonicalName
  var job: CompletableJob = Job()
  
  fun getData(
      token: String?,
      sslContext: SSLContext,
      matchId: Int
  ): LiveData&lt;ResponseModel&gt; {
      job = Job()
      return object : LiveData&lt;ResponseModel&gt;() {
          override fun onActive() {
              super.onActive()
              job.let { thejob -&gt;
                  CoroutineScope(thejob).launch {
                      try {
                          val apiResponse = ApiService(sslContext).getData(
                              token
                           
                          )
                          LogUtil.debugLog(TAG, &quot;apiResponse ${apiResponse}&quot;)
                          withContext(Dispatchers.Main) {
                              value = apiResponse
                          }
                      } catch (e: Throwable) {
                          LogUtil.errorLog(TAG, &quot;error: ${e.message}&quot;)
                          withContext(Dispatchers.Main) {
                              when (e) {
                                  is HttpException -&gt; {
                                      value =
                                          Gson().fromJson&lt;ResponseModel&gt;(
                                              (e as HttpException).response()?.errorBody()
                                                  ?.string(),
                                              ResponseModel::class.java
                                          )
                                  }
                                  else -&gt; value = ResponseModel(error = e)
                              }
                          }
  
                      } finally {
                          thejob.complete()
                      }
                  }
  
              }
          }
      }
  }
  
  fun cancelJob() {
      job.cancel()
  }
  </code></pre>
  <p>}</p>
  <p>ViewMode:</p>
  <pre><code>class DataViewModel : ViewModel() {
  val TAG = DataViewModel::class.java.canonicalName
  var mListener: DataListener? = null
  
  private val mGetDataRepository: GetDataRepository = GetDataRepository()
  
  
  fun getData() {
      LogUtil.debugLog(TAG, &quot;getData&quot;)
      if (mListener?.isInternetAvailable()!!) {
          mListener?.onStartAPI()
  
          val context = mListener?.getContext()
  
          val token: String? = String.format(
              context?.resources!!.getString(R.string.user_token),
              PreferenceUtil.getUserData(context).token
          )
  
          val sslContext = mListener?.getSSlContext()
  
          if (sslContext != null) {
              val getData =
                  mGetDataRepository.getData(
                      token
                  )
              LogUtil.debugLog(TAG, &quot;getData ${getData}&quot;)
              mListener?.onApiCall(getData)
          } else {
              LogUtil.debugLog(TAG, &quot;getData Invalid certificate&quot;)
              mListener?.onError(&quot;Invalid certificate&quot;)
          }
      } else {
          LogUtil.debugLog(TAG, &quot;getData No internet&quot;)
          mListener?.onError(&quot;Please check your internet connectivity!!!&quot;)
      }
      LogUtil.debugLog(TAG, &quot;Exit getData()&quot;)
  }
  </code></pre>
  <p>}</p>
  <p>Activity:</p>
  <pre><code>class DataActivity : AppCompatActivity() {
  val TAG = DataActivity::class.java.canonicalName
  lateinit var fragment: DataFragment
  
  override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      LogUtil.debugLog(TAG, &quot;onCreate: Enter&quot;)
  
      var binding: ActivityDataBinding =
          DataBindingUtil.setContentView(this, R.layout.activity_data)
      if (savedInstanceState == null) {
           fragment = DataFragment.newInstance()
          supportFragmentManager.beginTransaction().add(R.id.container, fragment, DataFragment.TAG)
      } else {
          fragment = supportFragmentManager.findFragmentByTag(DataFragment.TAG) as DataFragment
      }
  
      LogUtil.debugLog(TAG, &quot;onCreate: Exit&quot;)
  }
  </code></pre>
  <p>}</p>
  <p>Fragment:</p>
  <pre><code>class DataFragment : Fragment(), DataListener {
  private var mBinding: FragmentDataBinding? = null
  private lateinit var mViewModel: DataViewModel
  
  companion object {
      val TAG = DataFragment::class.java.canonicalName
      fun newInstance(): DataFragment {
          return DataFragment()
      }
  }
  
  override fun onCreateView(
      inflater: LayoutInflater,
      container: ViewGroup?,
      savedInstanceState: Bundle?
  ): View? {
      mBinding =
          DataBindingUtil.inflate(inflater, R.layout.fragment_data, container, false)
      mViewModel = ViewModelProvider(this).get(DataViewModel::class.java)
      mViewModel.mListener = this
      getData()
      return mBinding?.root
  }
  
  private fun getData() {
      LogUtil.debugLog(TAG, &quot;Enter getMatchScore()&quot;)
      mViewModel.getData()
      LogUtil.debugLog(TAG, &quot;Exit getMatchScore()&quot;)
  }
  
  override fun &lt;T&gt; onApiCall(response: LiveData&lt;T&gt;) {
      response.observe(this, Observer {
          it as DataResponseModel
          //
      })
  
  }
  </code></pre>
  <p>}</p>