title: MVVM: ViewModel is null when trying to load data using LiveData
body: <p>So I'm trying to build a simple MVVM interface to load trips from the database retrieved by the ViewModel into my TripFragment. However, I keep getting this error saying that my TripViewModel is null:</p>
  
  <pre><code>Attempt to invoke virtual method 'void androidx.lifecycle.LiveData.observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer)' on a null object reference
  </code></pre>
  
  <p>I can't seem to figure out why it thinks that it's null. I believe the issue is in TripViewModel and has something to do with how the fact that it inherits from AndroidViewModel and that I'm passing the application's context in the constructor.</p>
  
  <p>class TripFragment : Fragment()</p>
  
  <pre><code>private var tripViewModel: TripViewModel? = null
  private var textViewTripName: TextView? = null
  
  override fun onCreateView(
      inflater: LayoutInflater,
      container: ViewGroup?,
      savedInstanceState: Bundle?
  ): View? {
      val view =
          inflater.inflate(R.layout.fragment_trip, container, false)
  
      val recyclerView: RecyclerView = view.recycler_view
      recyclerView.layoutManager = LinearLayoutManager(context)
      recyclerView.setHasFixedSize(true)
  
      val adapter = TripAdapter()
      recyclerView.adapter = adapter
  
      tripViewModel = ViewModelProvider(this).get(TripViewModel(activity!!.application)::class.java)
  
  
      // This is the line where it crashes, it never executes past this
      tripViewModel!!.getAll().observe(viewLifecycleOwner, Observer&lt;List&lt;Trip&gt;&gt; {
          fun onChanged(trips: List&lt;Trip&gt;) {
              adapter.setTrips(trips)
              Log.d("TripFragment", "Went through observer")
          }
      })
  
      return view
  }
  </code></pre>
  
  <p>class TripViewModel(application: Application): AndroidViewModel(application)</p>
  
  <pre><code>private var tripRepository: TripRepository = TripRepository(application)
  private var allTrips: LiveData&lt;List&lt;Trip&gt;&gt; = getAll()
  
  fun insert(trip: Trip) {
      tripRepository.insert(trip)
  }
  
  fun update(trip: Trip) {
      tripRepository.update(trip)
  }
  
  fun delete(trip: Trip) {
      tripRepository.delete(trip)
  }
  
  fun clear() {
      tripRepository.clear()
  }
  
  fun getAll(): LiveData&lt;List&lt;Trip&gt;&gt; {
      return allTrips
  }
  </code></pre>
  
  <p>class TripRepository(application: Application) </p>
  
  <pre><code>private lateinit var tripDao: TripDao
  private lateinit var allTrips: LiveData&lt;List&lt;Trip&gt;&gt;
  
  init {
      CoroutineScope(IO).launch {
          tripDao = AppDatabase.getDatabase(application.applicationContext).tripDao()
          allTrips = tripDao.getAll()
      }
  }
  
  fun insert(trip: Trip) {
      CoroutineScope(IO).launch {
          tripDao.insert(trip)
      }
  }
  
  fun update(trip: Trip) {
      CoroutineScope(IO).launch {
          tripDao.update(trip)
      }
  }
  
  fun delete(trip: Trip) {
      CoroutineScope(IO).launch {
          tripDao.delete(trip)
      }
  }
  
  fun clear() {
      CoroutineScope(IO).launch {
          tripDao.clear()
      }
  }
  
  fun getAll(): LiveData&lt;List&lt;Trip&gt;&gt; {
      return allTrips
  }
  </code></pre>
  
  <p>Trip entity</p>
  
  <pre><code>@Entity
  data class Trip(var title: String, var startDate: String, var endDate: String?) {
  
      @PrimaryKey(autoGenerate = true)
      var tid: Long = 0
  }
  </code></pre>
  
  <p>EDIT: I've printed a bunch of debug logs and pinpointed the error at this line in <code>TripRepository</code>.</p>
  
  <pre><code>init {
      CoroutineScope(IO).launch {
          // tripDao is never assigned properly, 
          tripDao = AppDatabase.getDatabase(application.applicationContext).tripDao()
          allTrips = tripDao.getAll()
      }
  }
  </code></pre>
  
  <p>The line <code>tripDao = AppDatabase.getDatabase(application.applicationContext).tripDao()</code> causes an error which turns tripDao into a null variable. The problem has something to do with how I fetch the database, so I've attached my AppDatabase class below.</p>
  
  <pre><code>@Database(entities = [Trip::class], version = 2, exportSchema = false)
  abstract class AppDatabase : RoomDatabase() {
  
      abstract fun tripDao(): TripDao
  
      companion object {
          // Singleton prevents multiple instances of database opening at the
          // same time.
          @Volatile
          private var INSTANCE: AppDatabase? = null
  
          fun getDatabase(context: Context): AppDatabase {
              val tempInstance = INSTANCE
              if (tempInstance != null) {
                  Log.d("AppDatabase", "Returning existing database")
                  return tempInstance
              }
              synchronized(this) {
                  val instance = Room.databaseBuilder(
                      context.applicationContext,
                      AppDatabase::class.java,
                      "tripweaver_database"
                  )
                      .fallbackToDestructiveMigration()
                      .build()
                  INSTANCE = instance
                  Log.d("AppDatabase", "Returning new database")
                  return instance
              }
          }
      }
  }
  </code></pre>