org.kodein.di.Kodein$NotFoundException: No binding found for bind<LLApi>() with ?<LoginFragment>().? { ? }

805 views Asked by At

Iam doing a project with objectbox + retrofit + kodein. But I'm getting this error.

org.kodein.di.Kodein$NotFoundException: No binding found for bind<LLApi>() with ?<LoginFragment>().? { ? }

KodeinApplication.kt

class KodeinApplication : Application(), KodeinAware {
    override val kodein = Kodein.lazy {
        import(androidXModule(this@KodeinApplication))

        bind() from singleton { AppVersion }
        bind() from singleton { NetworkConnectivityInterceptor(instance()) }
        bind() from singleton { LLApi }
        bind() from singleton { LoginRepository(instance(), instance()) }
        bind() from provider { LoginViewModelFactory(instance()) }
    }
}

BaseRepository.kt

abstract class BaseRepository<T>(
    val service: LLApi,
    @PublishedApi internal val boxStore: BoxStore
) {
    abstract fun loadData(): LiveData<T>
    inline fun <reified T : Any> fetchData(crossinline call: (LLApi) -> Deferred<Response<T>>): LiveData<T> {
        val result = MutableLiveData<T>()

        CoroutineScope(Dispatchers.IO).launch {
            val request = call(service)
            withContext(Dispatchers.Main) {
                try {
                    val response = request.await()
                    if (response.isSuccessful) {
                        result.value = response.body()
                    } else {
                        Timber.d("Error occurred with code ${response.code()}")
                    }
                } catch (e: HttpException) {
                    Timber.d("Error: ${e.message()}")
                } catch (e: Throwable) {
                    Timber.d("Error: ${e.message}")
                }
            }
        }
        return result
    }

    inline fun <reified T : Any> saveToDatabase(data: T) {
        CoroutineScope(Dispatchers.IO).launch {
            boxStore.boxFor<T>().removeAll()  // deleting and inserting data to avoid sync issues
            boxStore.boxFor<T>().put(data)
        }

    }
}

LoginRepository.Kt

class LoginRepository(service: LLApi, store: BoxStore) :
    BaseRepository<UserInfo>(service, store) {

    private var loginRequest: LoginRequest? = null
    init {
        this.loginRequest = loginRequest
    }

    override fun loadData(): LiveData<UserInfo> {
        return fetchData { service.userLogin(loginRequest) }
    }

}

LoginViewModelFactory.kt

class LoginViewModelFactory(private val repository: LoginRepository) :
    ViewModelProvider.NewInstanceFactory() {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return LoginViewModel(repository) as T
    }
}

LoginViewModel.kt

class LoginViewModel(val repository: LoginRepository) : BaseViewModel<UserInfo>() {
    private lateinit var user: LiveData<UserInfo>
    override fun getDataFromService(): LiveData<UserInfo> {
        user = repository.loadData()
        return user
    }

    override fun saveTODatabase(data: UserInfo) {
        repository.saveToDatabase(data)
    }
}

LoginRequest.kt

data class LoginRequest(
    @SerializedName("mobile_no") val mobileNumber:String?,
    val password:String?
)

LoginFragment.kt

class LoginFragment() : Fragment(), KodeinAware {
    override val kodein by kodein()
    private  val factory: LoginViewModelFactory by instance()
    private  lateinit var binding: LoginFragmentBinding
    private  lateinit var viewModel: LoginViewModel

    private var emailOrPhone: EditText? = null
    private var password: EditText? = null

    companion object {
        fun newInstance(): LoginFragment {
            return LoginFragment()
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        binding = DataBindingUtil.setContentView(requireActivity(), R.layout.login_fragment)
        viewModel = ViewModelProvider(
            this, factory
            
        ).get(LoginViewModel::class.java)

        val view = inflater.inflate(R.layout.login_fragment, container, false)
        emailOrPhone = view?.findViewById(R.id.edt_number_or_email)
        password = view?.findViewById(R.id.edt_password)
        return view
    }

    fun userLoginService() {
        val email = binding.edtNumberOrEmail.text.toString()
        val password = binding.edtPassword.text.toString()

   
         val liveData = viewModel.getDataFromService()
         liveData.observe(this, Observer {
             if (it != null) {
                 viewModel.saveTODatabase(it)
             }
         })
    }
}

please feel free to ask for any files required and please help me with this issue.

1

There are 1 answers

0
waqas tasleem On

are you adding KodeinApplication class to the manifest.xml file like

<application android:name=".KodeinApplication "----/>