0

I am working on a simple contact app that stores the contact's name, email, and number. Language: Kotlin Architecture: MVVM But I am getting an error: lateinit property addContactViewModel has not been initialized

Activity:

class AddContact : AppCompatActivity() { private lateinit var addContactViewModel : AddContactViewModel companion object{ const val EXTRA_REPLY = "com.room.contacts.REPLY" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding = DataBindingUtil.setContentView<ActivityAddContactBinding>( this,R.layout.activity_add_contact ) binding.btnSave.setOnClickListener { val replyIntent = Intent() val fname= binding.fnameEdit.text.toString() val lname= binding.lnameEdit.text.toString() val email = binding.emailAddressEdit.text.toString() val contactno = binding.contactNumberEdit.text.toString() val contact = Contact(fname, lname,email,contactno) addContactViewModel.insert(contact) val intent = Intent(this, ContactList::class.java) // start your next activity startActivity(intent) } }} 

ViewModel:

class AddContactViewModel (application: Application) : AndroidViewModel(application){ private val repository: ContactRepository init { val contactsDao= ContactRoomDatabase.getDatabase(application).contactDao() repository = ContactRepository(contactsDao) } fun insert(contact: Contact) = viewModelScope.launch { repository.insert(contact) }} 

Error:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.room.contacts, PID: 29383 kotlin.UninitializedPropertyAccessException: lateinit property addContactViewModel has not been initialized at com.room.contacts.screens.addContact.AddContact.access$getAddContactViewModel$p(AddContact.kt:15) at com.room.contacts.screens.addContact.AddContact$onCreate$1.onClick(AddContact.kt:36) at android.view.View.performClick(View.java:4781) at android.view.View$PerformClick.run(View.java:19907) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:160) at android.app.ActivityThread.main(ActivityThread.java:5541) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759) 
4
  • You should initialize addContactViewModel in oncreate, not in setOnClickListener Commented Apr 24, 2020 at 17:21
  • @MohammadMoeinGolchin yes! that makes sense! resolved it like that. Thanks Commented Apr 24, 2020 at 17:39
  • Why did you change the correct answer? Commented Apr 25, 2020 at 18:19
  • Your answer is correct as well. I dig deep into it and seems like the better way to do things is to use the lazy property. Your answer is correct but the other one seems like a better option. Commented Apr 25, 2020 at 18:50

2 Answers 2

3

Instead of having your addContactViewModel as a lateinit property you can make it a lazy property, so that it gets initialized the first time you try to use it somewhere:

class AddContact : AppCompatActivity() { private val addContactViewModel : AddContactViewModel by lazy { ViewModelProvider(this).get(AddContactViewModel::class.java) } 
Sign up to request clarification or add additional context in comments.

2 Comments

this works too! But rather than instantiating the lateinit var in the listener, I instantiated it in onCreate and that worked for me. This Solution works as well.
Yeah, both work. But a lazy property has the benefit that you can't forget to initialize it. And you can make it a val, unlike a lateinit property which must be a var.
0

You should initialize addContactViewModel in oncreate, not in setOnClickListener

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.