Kanan
Kanan

Reputation: 177

lateinit property data has not been initialized

Gson Convertable data is not set in Recyclerview using Retrofit2 and rxjava2 then subscribe throughble its Give Error:

UninitializedPropertyAccessException: lateinit property data has not been initialized

JSON data parsing by retrofit2 and rxjava2. when parsing GSON Data Converting GSon, rxjava2 Subscribe the data then give lateinit property error and its not set in recyclerview.

MainActivity.kt

class Company : AppCompatActivity() {


    internal lateinit var api : APIInterface

    var compositeDisposable = CompositeDisposable()



    internal lateinit var companyDialog : Dialog

    internal lateinit var adapter: CompanyAdapter

    internal lateinit var data : List<Company>

    internal lateinit var rvCompany : RecyclerView

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

        companyDialog = Dialog(this)

        //companyAdapter = CompanyAdapter()


        btnSelectCompany.setOnClickListener{
            showCompanyPopupView()
        }



    }

    fun showCompanyPopupView(){
        companyDialog.setContentView(R.layout.compny_popup_screen)

         rvCompany  = companyDialog.findViewById(R.id.rvCompany)

        rvCompany.setHasFixedSize(true)
        rvCompany.layoutManager = LinearLayoutManager(this) as RecyclerView.LayoutManager?

        fetchData()
        companyDialog.window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        companyDialog.show()
    }

    private fun fetchData(){

        val retrofit = APIClient.apIClient
        if (retrofit != null) {
            api = retrofit.create(APIInterface::class.java)
        }
        compositeDisposable.add(api.getCompanyData()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe ({ companyList-> displayData(data)
                },{
                    Toast.makeText(applicationContext, it.message, Toast.LENGTH_SHORT).show()
                })

        )

    }


    private fun displayData(companyList: List<Company>) {


        adapter = CompanyAdapter(this,companyList)
        rvCompany.adapter = adapter

    }


}

CompanyAdapter.kt

class CompanyAdapter(internal var context: Context, internal var companyList: List<Company>)
    :RecyclerView.Adapter<CompanyAdapter.CompanyViewHolder>()
{
    override fun onCreateViewHolder(p0: ViewGroup, p1: Int): CompanyViewHolder {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.

        val itemView = LayoutInflater.from(p0.context).inflate(R.layout.list_view_item,p0,false)

        return CompanyViewHolder(itemView)
    }

    override fun getItemCount(): Int {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        return companyList?.size!!
    }

    override fun onBindViewHolder(p0: CompanyViewHolder, p1: Int) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.

       // p0.rbButton.text = this!!.companyList?.get(p1)?.Cmp_Name
        p0.bindModel(companyList[p1])
    }

    inner class CompanyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){

        val radioButton : RadioButton = itemView.findViewById(R.id.rbCompanyName)

        fun bindModel(company: Company){

            radioButton.text = company.Cmp_Name
        }
    }



}

Upvotes: 5

Views: 21872

Answers (2)

Kanchan Pal
Kanchan Pal

Reputation: 367

You are using un-initialised variable data in displayData(data) function. Rather pass companyList what you are getting from subscribe function as follows.

 private fun fetchData(){

        val retrofit = APIClient.apIClient
        if (retrofit != null) {
            api = retrofit.create(APIInterface::class.java)
        }
        compositeDisposable.add(api.getCompanyData()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe ({ companyList-> displayData(companyList)
                },{
                    Toast.makeText(applicationContext, it.message, Toast.LENGTH_SHORT).show()
                })

        )

    }

Also you can save companyList which you've got in your data variable first, before using it to avoid the error. Doing so will help you use this companyList at some other place in class Company instead of just passing in function.

compositeDisposable.add(api.getCompanyData()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe ({ companyList-> 
                        data = companyList
                        displayData(data)
                },{
                    Toast.makeText(applicationContext, it.message, Toast.LENGTH_SHORT).show()
                })

        )

Upvotes: 1

Alexey Romanov
Alexey Romanov

Reputation: 170835

The error happens because you never initialize it (data = ...), but you access it in { companyList-> displayData(data) }. This ignores the companyList you get from subscribe, which is probably not what you actually want.

Your code seems to overuse lateinit a lot. Use it when you really need it.

Upvotes: 2

Related Questions