kotlin.UninitializedPropertyAccessException: lateinit property salesGST Model class has not instalized - kotlin

Json Data parse using Retrofit2 and rxjav2. then its give error of lateinit Property of salesGST :
"kotlin.UninitializedPropertyAccessException: lateinit property salesGST has not been initialized"
Model Class SalesGSTList in JSONObject key success after SalesGST data in ArrayList.
class SalesGSTList {
val success : String = ""
lateinit var salesGST: ArrayList<SalesGST>
}
JSON Key declare in SalesGST.
class SalesGST {
var FYearID : Int = 0
var Cmp_Name : String? = ""
var GSTIN : String? = ""
var FirmName : String? = ""
}
Parsing Json data Display in Textview and TableLayout. when data Subscribe then give error.
sales.kt
class Sales : AppCompatActivity() {
internal lateinit var api : APIInterface
private var compositeDisposable : CompositeDisposable? = null
private var salesGST : SalesGST? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sales)
compositeDisposable = CompositeDisposable()
fetchYearData()
}
private fun fetchYearData(){
val retrofit = APIClient.apIClient
if (retrofit != null) {
api = retrofit.create(APIInterface::class.java)
}
/*compositeDisposable!!.add(api.getSalesGSTData(cid,fid,fDate,tDate)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { displaySalesGSTData(it.salesGST) })*/
compositeDisposable!!.add(api.getSalesGSTData(1,1,"04/01/2018","31/03/2019")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe( {
displaySalesGSTData(it.salesGST) },
{
Toast.makeText(this,it.message,Toast.LENGTH_LONG).show()
}))
}
private fun displaySalesGSTData(salesGSt : List<SalesGST>) {
salesGST = SalesGST()
tvSalesCompanyName.setText(salesGST!!.Cmp_Name)
tvGSTIN.setText(salesGST!!.GSTIN)
val rowHeader = TableRow(this#Sales)
rowHeader.setBackgroundColor(Color.parseColor("#c0c0c0"))
rowHeader.setLayoutParams(TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT))
val headerText = arrayOf<String>("Sr.No.", "Invoice Type", "Bill No.", "Bill Date", "Firm Name", "GST NO","TAX Total","CGST","SGST","IGST","Net Amount")
for (c in headerText)
{
val tv = TextView(this#Sales)
tv.setLayoutParams(TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT))
tv.setGravity(Gravity.CENTER)
// tv.setBackgroundResource(R.drawable.table_header)
tv.setTextColor(Color.parseColor("#3F51B5"))
tv.setTextSize(18F)
tv.setPadding(5, 5, 5, 5)
tv.setText(c)
rowHeader.addView(tv)
}
tableMarks.addView(rowHeader)
for (j in 0 until salesGSt.size)
{
var fName : String = salesGSt[j].FirmName!!
var invoice : String = salesGSt[j].InvoiceType!!
var bill_no : String = salesGSt[j].ChallanNo!!
var bill_date : String = salesGSt[j].ChallanDate!!
var gst_no : String = salesGSt[j].PartyGST!!
var tax_total : String = salesGSt[j].TaxTotal!!
var cgst : String = salesGSt[j].CGSTTotal!!
var igst : String = salesGSt[j].IGSTTotal!!
var sgst : String = salesGSt[j].SGSTTotal!!
var net_amount : String = salesGSt[j].ChallanAmount!!
var sr : Int = j
// dara rows
val row = TableRow(this#Sales)
row.setLayoutParams(TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT))
val colText = arrayOf<String>(sr.toString(),(invoice), bill_no, bill_date, fName, gst_no,tax_total,cgst,sgst,igst,net_amount)
for (text in colText)
{
val tv = TextView(this#Sales)
tv.setLayoutParams(TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT))
tv.setGravity(Gravity.CENTER)
// tv.setBackgroundResource(R.drawable.table_shape)
tv.setTextSize(18F)
tv.setTextColor(Color.parseColor("#000000"))
tv.setPadding(5, 5, 5, 5)
tv.setText(text)
row.addView(tv)
}
tableMarks.addView(row)
}
}
}
Interface
#GET("SalesGST.php")
fun getSalesGSTData(#Query("cid") cid : Int,#Query("fid") fid : Int,#Query("fd") fd : String,#Query("td") td : String) : Observable<SalesGSTList>

This error is really clear. You try to use your variable salesGST before you initialized it.
I guess this is coming from here:
class SalesGSTList {
val success : String = ""
// salesGST expects to be initialize soon and is never initialized
lateinit var salesGST: ArrayList<SalesGST>
}
You should either do a lazy initialization of salesGST, or set it as:
var salesGST: ArrayList<SalesGST>? = null

Related

In Kotlin, why the load method from Neo4j OGM returns null if the #Id property is named "id"?

Using the sample below (based on this source but with some changes), if the property #Id is named "id", the Neo4J (latest version) does not recognizes the attribute when the load is executed. But if I named it to any other name, such as "myId", the method works. Please, does anyone know why?
My code:
package sample
import org.neo4j.ogm.annotation.Id
import org.neo4j.ogm.annotation.NodeEntity
import org.neo4j.ogm.annotation.Relationship
import org.neo4j.ogm.config.Configuration
import org.neo4j.ogm.session.SessionFactory
#NodeEntity
data class Actor(
#Id
var id: Long?,
var name:String
) {
constructor() : this(-1, "")
#Relationship(type = "ACTS_IN", direction = "OUTGOING")
var movies = mutableSetOf<Movie>()
fun actsIn(movie: Movie) {
movies.add(movie)
movie.actors.add(this)
}
}
#NodeEntity
data class Movie(
#Id
var id: Long?,
var title:String,
var released:Int
) {
constructor() : this(-1L, "", -1)
#Relationship(type = "ACTS_IN", direction = "INCOMING")
var actors = mutableSetOf<Actor>()
}
class Sample {
private val uri = "bolt://localhost:7687"
val configuration = Configuration.Builder()
.uri(uri)
//.credentials("neo4j", "test")
.build()
val sessionFactory = SessionFactory(configuration, "sample")
fun save() {
val pack = SessionFactory::class.java.name
val l = java.util.logging.Logger.getLogger(pack)
l.setLevel(java.util.logging.Level.ALL)
val session = sessionFactory.openSession()
val develsAdvocate = Movie(1, "The Devil’s Advocate", 1997)
val theMatrix = Movie(2, "The Matrix", 1999)
val act = Actor(1, "Carrie-Anne Moss")
act.actsIn(theMatrix)
val keanu = Actor(2, "Keanu Reeves")
keanu.actsIn(theMatrix)
keanu.actsIn(develsAdvocate)
session.save(develsAdvocate)
session.save(theMatrix)
session.clear()
// ** Only works if the entity has a attribute #Id with name different as "id"
val theMatrixReloaded = session.load(Movie::class.java, theMatrix.id, 2)
println("Found ${theMatrixReloaded.title}")
for (actor in theMatrixReloaded.actors) {
println("Actor ${actor.name} acted in ${actor.movies.joinToString { it.title }}")
}
sessionFactory.close()
}
}
fun main(args: Array<String>) {
val neoInstance = Sample()
neoInstance.save()
}

How to pass data/object from fragment to activity in kotlin

I am tring to pass a list of datas from a fragment to a activity using intent. When sending the data from fragment, the data is exist. But in activity the its says data is null. I am not sure if the way i pass the data is correct or not or is there any better way to pass the data from fragment to activity?
In Fragment
private var selectedBankCard: Channels = Channels //get a list of data from BE
override fun onClick(view: View?) {
when (view?.id) {
R.id.bankcard_layout -> {
try {
if (activity != null) {
val intent =
Intent(context, BankCardListActivity::class.java)
if (selectedBankCard != null) {
intent.putExtra("BANKCARDINFORMATION", selectedBankCard) //upon debug, i can see a selectedBankCard is not null
}
startActivityForResult(intent, 10001)
}
} catch (e: Exception) {
}
}
}
}
}
In Activity
class AutoReloadBankCardListActivity : BaseActivity() {
private lateinit var channels: Channels
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.bank_card)
if (intent == null) {
return
}
channels = intent.getSerializableExtra("BANKCARDINFORMATION") as Channels // upon debug, getSerializableExtra returns null
}
class Channels : Serializable {
var newCard = false
var disable = false
var disableCode: String = ""
var description: String = ""
var channelType: String = ""
var payBrands: List<String>? = null
var channelIndex: String = ""
var payToolType: String = ""
var selected = false
var payBrand: String = ""
var extendInfo: ExtendInfo? = null
var disableReason: String = ""
var icon: String = ""
var chargeIndex: String = ""
}
better way to pass the data from fragment to activity?
Better way is listener. You can use interface or lambda in kotlin.
Your fragment. Category is your data/object in this example
class MyFragment : Fragment() {
var listener: ((category: Category) -> Unit)? = null
fun sendCategoryToListener(category: Category) {
listener?.invoke(category)
}
}
Code in your activity
val fragment = MyFragment()
fragment.listener = { category ->
// Do what you want with your object
}
Can you provide the class definition of selectedBankCard?
The type of selectedBankCard must implement the Serializable interface, otherwise the data cannot be obtained in the Activity.
data class Channels(
var newCard = false,
var disable = false,
var disableCode: String = "",
var description: String = "",
var channelType: String = "",
var payBrands: List<String>? = null,
var channelIndex: String = "",
var payToolType: String = "",
var selected = false,
var payBrand: String = "",
var extendInfo: ExtendInfo? = null,
var disableReason: String = "",
var icon: String = "",
var chargeIndex: String = ""
) : Serializable
if you use this code to start a fragment from an activity then you can easily get the return data like this.
Code to start fragment
fun addFragment(
fragment: Fragment,
) {
supportFragmentManager.beginTransaction()
.add(R.id.nav_host_fragment, fragment)
.addToBackStack(BACK_STACK)
.commit()
}
addFragment(ABCFragment(item->{//here the item is your return data}))
You can add fragment like this
and to get return data you can add fragment like this
addFragment(ABCFragment( private val returnData: (item: ABCModel) -> Unit,))
and in fragment write this code
class ABCFRagment(private val returnData: (item: ABCModel) -> Unit,):Fragment{
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
item.invoke(data)
}}
and in activity you can get your return data as item

Could not find Fragment constructor kotlin

When creating a popular fragment, I get an empty constructor error.
Please take a look at the code I wrote and how can I pass data when creating fragments?
mAdapter = SubPagerAdapter(childFragmentManager)
for (doc in it.docs!!) {
mAdapter.addFragment(
PopularFragment(doc.code, "#${doc.name}", 10),
doc.name
)
}
viewpager.adapter = mAdapter
tabs.setupWithViewPager(viewpager)
class PopularFragment(private val hashTagsCode: Int, private val title: String, private val ItemCount: Int) : Fragment() {
var mHashTagsCode = hashTagsCode
var mTitle = title
var mItemCount = ItemCount
}
You should always pass the data to Fragment using Bundle as arguments
class PopularFragment : Fragment() {
var mHashTagsCode = 0
lateinit var mTitle :String
var mItemCount = 0
companion object{
fun instance(hashTagsCode: Int, title: String, itemCount: Int){
val data = Bundle()
data.putString("hash_tag_codes", hashTagsCode)
data.putString("title", title)
data.putString("item_count", itemCount)
return PopularFragment().apply{
arguments = data
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
mItemCount = arguments?.getInt("item_count")?:0
mHashTagsCode = arguments?.getInt("hash_tag_codes")?:0
mTitle = arguments?.getString("title")
}
}
And for creating instance
mAdapter = SubPagerAdapter(childFragmentManager)
for (doc in it.docs!!) {
mAdapter
.addFragment(PopularFragment.intsance(doc.code, "#${doc.name}", 10),doc.name)
}
viewpager.adapter = mAdapter
tabs.setupWithViewPager(viewpager)

Cannot infer a type for this parameter please specify it explicitly?

I have recently developed android app using Kotlin but I am getting the following error
Cannot infer a type for this parameter. Please specify it explicitly
below screenshot of the error
below my class where I am getting error
class AddBookingActivity : AppCompatActivity() {
#BindView(R.id.attendees_recycler_view)
internal var mAttendeeRecyclerView: RecyclerView? = null
#BindView(R.id.start_time_edit_text)
internal var mStartTime: EditText? = null
#BindView(R.id.end_time_edit_text)
internal var mEndTime: EditText? = null
private var mAttendeeName: EditText? = null
private var mAttendeeEmail: EditText? = null
private var mAttendeePhoneNumber: EditText? = null
private var mAttendeeAdapter: AttendeeAdapter? = null
private var mAlertDialog: AlertDialog? = null
private val mAttendeeItemList = ArrayList<AttendeeItem>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_booking)
ButterKnife.bind(this)
mAttendeeRecyclerView!!.layoutManager = LinearLayoutManager(this)
mAttendeeAdapter = AttendeeAdapter(this)
mAttendeeAdapter!!.setAttendeeList(mAttendeeItemList)
mAttendeeRecyclerView!!.adapter = mAttendeeAdapter
}
#OnClick(R.id.toolbar_back_button)
internal fun onBackButtonClicked() {
onBackPressed()
}
#OnClick(R.id.start_time_edit_text)
internal fun onStartTimeClicked() {
showTimePickerDialog(mStartTime)
}
#OnClick(R.id.end_time_edit_text)
internal fun onEndTimeClicked() {
showTimePickerDialog(mEndTime)
}
#OnClick(R.id.fab_add_attendee)
internal fun onAddAttendeeClicked() {
val inflater = this.layoutInflater
val dialogView = inflater.inflate(R.layout.add_attendee_view, null)
mAttendeeName = dialogView.findViewById(R.id.attendee_name)
mAttendeeEmail = dialogView.findViewById(R.id.attendee_email)
mAttendeePhoneNumber = dialogView.findViewById(R.id.attendee_phone_number)
mAlertDialog = AlertDialog.Builder(this, R.style.AlertDialog)
.setTitle("Input attendee details")
.setPositiveButton("Add") { dialog, which ->
val item = AttendeeItem()
item.name = mAttendeeName!!.text.toString()
item.email = mAttendeeEmail!!.text.toString()
item.phoneNumber = mAttendeePhoneNumber!!.text.toString()
mAttendeeItemList.add(item)
mAttendeeAdapter!!.setAttendeeList(mAttendeeItemList)
mAttendeeAdapter!!.notifyItemInserted(mAttendeeItemList.size)
}
.setNegativeButton("Cancel", null)
.setView(dialogView).create()
mAlertDialog!!.show()
}
private fun showTimePickerDialog(editText: EditText?) {
val myCalender = Calendar.getInstance()
val hour = myCalender.get(Calendar.HOUR_OF_DAY)
val minute = myCalender.get(Calendar.MINUTE)
#SuppressLint("DefaultLocale")
val myTimeListener = { view, hourOfDay, minute1 ->
if (view.isShown()) {
myCalender.set(Calendar.HOUR_OF_DAY, hourOfDay)
myCalender.set(Calendar.MINUTE, minute1)
editText!!.setText(String.format(String.format("%s:%s", hourOfDay.toString(), minute1.toString())))
}
}
val timePickerDialog = TimePickerDialog(this, android.R.style.Theme_Holo_Light_Dialog_NoActionBar, myTimeListener, hour, minute, true)
timePickerDialog.setTitle("Choose hour:")
timePickerDialog.window!!.setBackgroundDrawableResource(android.R.color.transparent)
timePickerDialog.show()
}
}
You have to specify the interface to help Kotlin compiler:
#SuppressLint("DefaultLocale")
val myTimeListener = TimePickerDialog.OnTimeSetListener { view, hourOfDay, minute1 ->
if (view.isShown()) {
myCalender.set(Calendar.HOUR_OF_DAY, hourOfDay)
myCalender.set(Calendar.MINUTE, minute1)
editText!!.setText(String.format(String.format("%s:%s", hourOfDay.toString(), minute1.toString())))
}
}

Why protected var is KProperty and public/private var is KMutableProperty?

In each of the following cases I have some mutable var properties. According to Javadocs mutable properties are represented by KMutableProperty but in these examples protected property is represented by KProperty class. Why is that so?
class FooA {
var publicProp: String? = null
protected var protectedProp: String? = null
private var privateProp: String? = null
fun foo() {
val a = ::publicProp
val b = ::protectedProp
val c = ::privateProp
}
}
open class FooB {
var publicProp: String? = null
protected var protectedProp: String? = null
private var privateProp: String? = null
fun foo() {
val a = ::publicProp
val b = ::protectedProp
val c = ::privateProp
}
}
class Bar : FooB() {
fun bar() {
val a = ::publicProp
val b = ::protectedProp
}
}
Type hints from IDEA