Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UninitializedPropertyAccessException: lateinit property has not been initialized

I have a class which i inject into a ViewModel + ViewModel factory, when initialise the view model in the onCreate method in activity, its says the value being passed through is not initialised.

Below is my code

I am quite new to Kotlin so have tried debugging but am stuck on this issue.

Here is MainActivity code:

class MainActivity: AppCompatActivity(), RepoSelectedListener {


    @Inject
    lateinit var viewModel: MainActivityListViewModel

    lateinit var lifecycleOwner: LifecycleOwner
    lateinit var repoSelectedListener: RepoSelectedListener

    @Inject
    lateinit var repository: RepoRepository


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel = ViewModelProviders.of(this, ViewModelFactory(repository)).get(MainActivityListViewModel::class.java)

        repoRecyclerView.apply {
            layoutManager = LinearLayoutManager(context)
            adapter = RepoListAdapter(viewModel, lifecycleOwner, repoSelectedListener)
        }


**My ViewModel:**



   class MainActivityListViewModel @Inject constructor(val 
    repoRepository: RepoRepository): BaseViewModel() {

    //private lateinit var repoRepository: RepoRepository
    private var disposable: CompositeDisposable? = null

    private val repos = MutableLiveData<List<Repo>>()
    private val repoLoadError = MutableLiveData<Boolean>()
    private val loading = MutableLiveData<Boolean>()


     init {
        disposable = CompositeDisposable()
        fetchRepos()
      }

     fun getRepos(): LiveData<List<Repo>> {
        return repos
     }
    }

my ViewModelFactory:

   class ViewModelFactory @Inject constructor(private val 
   repoRepository: RepoRepository): ViewModelProvider.Factory{


    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if 
   (modelClass.isAssignableFrom(MainActivityListViewModel::class.java)) 
   {
            @Suppress("UNCHECKED_CAST")
            return MainActivityListViewModel(this.repoRepository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")

    }


   }

my Class Repo:

  class RepoRepository @Inject constructor(private val githubRepos: 
    GithubRepos){


    private lateinit var repoService: GithubRepos


    fun getRepositories(): Single<List<Repo>> {
        return repoService.getRepos()
    }

    fun getSingleRepo(owner: String, name: String): Single<Repo> {
        return repoService.getSingleRepo(owner, name)
    }
   }

This is error i receive:

   Unable to start activity ComponentInfo{com.carllewis14.repos/com.carllewis14.repos.ui.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property 
  repository has not been initialized
like image 823
DanYon Avatar asked Jul 24 '19 12:07

DanYon


People also ask

How do you check if a Lateinit property has been initialized?

You can check if the lateinit variable has been initialized or not before using it with the help of isInitialized() method. This method will return true if the lateinit property has been initialized otherwise it will return false.

What does Lateinit mean?

lateinit means late initialization. If you do not want to initialize a variable in the constructor instead you want to initialize it later on and if you can guarantee the initialization before using it, then declare that variable with lateinit keyword. It will not allocate memory until initialized.


2 Answers

This is because you are trying to use the repository before initializing it with an instance without checking its initialization.

When using lateinit nullity cannot be used in that variable.

lateinit var repository: RepoRepository

Then, before using any method of the object, check that it is initialized:

if (::repository.isInitialized) {}

GL

like image 115
Braian Coronel Avatar answered Oct 24 '22 08:10

Braian Coronel


have a look at my answer here (maybe it helps ) Nullable var with `?` vs. lateinit var

Essentially, you are never initializing your repository: RepoRepository.

From the code you have written, you won't need an instance of your repository in your activity as well, it should just be created in the constructor of your ViewModel (which has injection)

You are also going to have a similar issue with private lateinit var repoService: GithubRepos; if it's in the constructor of your object, you don't have to declare it again.

like image 20
a_local_nobody Avatar answered Oct 24 '22 06:10

a_local_nobody