I am new to dagger 2 and kotlin both. Getting lateinit property not initialized.
I have a module which have few @Provides methods but one of the class not able to create object which used @Inject and lateinit.
Login service takes "LoginAPI" as parameter and works fine but as i want all my login related API's to use the same service. There is one more API related "LoginWithOrgAPI".
Now my need is to get any API object when needed in the LoginService class. So i tries using lateinit with @Inject as show in LoginService class but its not working.
@Module(includes = [(NetworkingModule::class)])
class LoginModule {
@Provides
fun provideLoginApi(retrofit: Retrofit): LoginApi =
retrofit.create(LoginApi::class.java)
@Provides
fun provideLoginWithOrgApi(retrofit: Retrofit): LoginWithOrgApi =
retrofit.create(LoginWithOrgApi::class.java)
@Provides
fun provideLoginService(api: LoginApi): LoginService =
LoginService(api)
@Provides
fun provideLoginInteractor(apiService: LoginService): LoginInteractor =
LoginInteractor(apiService)
}
// adding LoginService class
class LoginService(val loginAPI: LoginApi) {
@Inject
lateinit var loginWithOrgApi: LoginWithOrgApi
fun loginAPIService(user: String, password: String?, extension: String, otp: String?,
hardwareId: String): Single<LoginAPIResponseData> {
password?.let {
return loginAPI.getLogin(user, it, extension, null, hardwareId)
}?: run {
return loginAPI.getLogin(user, null, extension, otp, hardwareId)
}
}
fun loginWithOrg(user: String, password: String?, extension: String, otp: String?,
userId: String, hardwareId: String): Single<LoginAPIResponseData>{
password?.let {
return loginWithOrgApi.getLogin(user, it, extension, null, userId, hardwareId)
}?: run {
return loginWithOrgApi.getLogin(user, null, extension, otp, userId, hardwareId)
}
}
}
// component
@Component(modules = [(LoginModule::class)])
interface LoginComponent {
fun loginInteractor(): LoginInteractor
}
// api interface
interface LoginWithOrgApi {
@POST("access/v1/login/")
@FormUrlEncoded
fun getLogin(@Field("user") user: String,
@Field("password") password: String?,
@Field("mobile_extension") extension: String,
@Field("otp") otp: String?,
@Field("user_id") userId: String,
@Field("hardware_id") hardwareId: String): Single<LoginAPIResponseData>
}
Getting the crash saying "lateinit" property not initialized when trying to call method "loginWithOrg"
My understanding is that once define and provided through module, i can get the object through @Inject in the dependency graph but something is missing here.
// my objective for LoginService class
class LoginService() {
@Inject
var loginWithOrgApi: LoginWithOrgApi
@Inject
var loginApi: LoginApi
fun loginAPIService(user: String, password: String?, extension: String, otp: String?,
hardwareId: String): Single<LoginAPIResponseData> {
password?.let {
return loginAPI.getLogin(user, it, extension, null, hardwareId)
}?: run {
return loginAPI.getLogin(user, null, extension, otp, hardwareId)
}
}
fun loginWithOrg(user: String, password: String?, extension: String, otp: String?,
userId: String, hardwareId: String): Single<LoginAPIResponseData>{
password?.let {
return loginWithOrgApi.getLogin(user, it, extension, null, userId, hardwareId)
}?: run {
return loginWithOrgApi.getLogin(user, null, extension, otp, userId, hardwareId)
}
}
}
LoginService(api)
), but I don't see you injecting it—hence the fields won't be set. You should have a look at constructor injection which would reduce the boilerplate and fix your issue – David Medenjak