Convert a Map to an Object in Kotlin - java

Hello guys I have a simple question ,
I have a Map full of element and I want to convert It in my Object , let me show you some code :
Here is my Object :
class Bundle(map: Map<String, Any>) {
var version: String?
var app: String?
var countries: ArrayList<Any>?
var currency: ArrayList<Any>?
var force: Boolean?
var name: String?
var service: ArrayList<Any>?
var money: Int?
init {
version= null
app= null
countries= arrayListOf()
currency= arrayListOf<Any>()
force= true
name = ""
service= arrayListOf<Any>()
money= 0
}
}
And there is the Map that i want to convert:
fun getBundle() {
var db = FirebaseFirestore.getInstance()
val docRef = db.collection("aa").document("bb")
docRef.get().addOnCompleteListener { task ->
if (task.isSuccessful) {
val document = task.result
if (document.exists()) {
Log.d("Doc", "DocumentSnapshot data: " + document.data!!)
// Here i want to take (document.data!!) and convert it to my Bundle class
} else {
Log.d("NO doc", "No such document")
}
} else {
Log.d("ERROR", "get failed with ", task.exception)
}
}
}
Thank you !

Ok I found the solution
I transformed my Bundle class in a data class :
data class Bundle(
var version: String? = null,
var app: String? = null,
var countries: ArrayList<Any> = arrayListOf(),
var currency: HashMap<String, Any> = hashMapOf(),
var force: Boolean = false,
var name: String? = null,
var service: ArrayList<Any> = arrayListOf(),
var money: Int = 0
)
And then I simply added this on my method , where I want to convert my Map to my Bundle Object :
val myObject = document.toObject(Bundle::class.java)

Related

An annotation argument must be a compile-time constant when trying to convert java enum

I tried to convert a java file to kotlin file but i'm getting this error : An annotation argument must be a compile-time constant
#StringDef(
BillingEnum.ALL,
BillingEnum.PAID,
BillingEnum.PENDING,
BillingEnum.OVERDUE,
BillingEnum.OPEN,
BillingEnum.DELETED
)
annotation class BillingEnum {
companion object {
var ALL = ""
var PAID = "paid"
var PENDING = "pending"
var OVERDUE = "overdue"
var OPEN = "open"
var DELETED = "deleted"
}
}
Before it looked like this:
#StringDef({
BillingEnum.ALL,
BillingEnum.PAID,
BillingEnum.PENDING,
BillingEnum.OVERDUE,
BillingEnum.OPEN,
BillingEnum.DELETED
})
public #interface BillingEnum {
String ALL = "";
String PAID = "paid";
String PENDING = "pending";
String OVERDUE = "overdue";
String OPEN = "open";
String DELETED = "deleted";
}
You must write
annotation class BillingEnum {
companion object {
const val ALL = ""
const val PAID = "paid"
const val PENDING = "pending"
const val OVERDUE = "overdue"
const val OPEN = "open"
const val DELETED = "deleted"
}
}

Should Getters and Setters in Kotlin be the same as Java in Android

This Model class has getters and setters implemented the same as in Java but now written in Kotlin
class HousePost{
private var uid: String = ""
private var postImage: String = ""
private var rent: String = ""
private var description: String = ""
private var publisher: String = ""
private var location: String = ""
private var postId: String? = ""
private var rooms: String = ""
private var caption: String = ""
private var dateTime: String = ""
var expandable: Boolean = false
constructor()
constructor(
uid: String,
postImage: String,
rent: String,
description: String,
location: String,
postId: String,
publisher: String,
rooms: String,
caption: String,
dateTime : String
) {
this.uid = uid
this.postImage = postImage
this.rent = rent
this.description = description
this.location = location
this.postId = postId
this.publisher = publisher
this.rooms = rooms
this.caption = caption
this.dateTime = dateTime
this.expandable = false
}
//Post Details getters
fun getUid() : String {
return uid
}
fun getPostId (): String? {
return postId
}
fun getPostImage():String {
return postImage
}
fun getDescription():String {
return description
}
fun getLocation():String {
return location
}
fun getRent():String {
return rent
}
fun getPublisher(): String {
return publisher
}
fun getRooms(): String {
return rooms
}
fun getCaption() : String {
return caption
}
fun getDateTime() : String {
return dateTime
}
//Post Details setters
fun setUid (uid: String) {
this.uid = uid
}
fun setPostId(postId: String) {
this.postId = postId
}
fun setPostImage(postImage: String) {
this.postImage = postImage
}
fun setLocation(location: String) {
this.location = location
}
fun setDescription(description: String) {
this.description = description
}
fun setRent(rent: String) {
this.rent = rent
}
fun setPublisher(publisher: String) {
this.publisher = publisher
}
fun setCaption(caption: String) {
this.caption = caption
}
fun setDateTime(dateTime: String) {
this.dateTime = dateTime
}
}
This class is supposed to model data from my database. Is that the correct way in Kotlin?
There is a No setter/field for class found error I'm getting. My recyclerview does not show the data at all, I assume is due to the error.
In Kotlin, a property doesn’t require explicit getter or setter methods.
Properties in Kotlin classes can be declared either as mutable, using the var keyword, or as read-only, using the val keyword.
A class whose main purpose is to hold data in Kotlin these are called data classes and are marked with data.
For example in your case the class can be define as below:
data class HousePost(
val uid: String = ""
val postImage: String = ""
val rent: String = ""
val description: String = ""
val publisher: String = ""
val location: String = ""
val postId: String? = ""
val rooms: String = ""
val caption: String = ""
val dateTime: String = ""
val expandable: Boolean = false
)
The val keyword make the properties of this data class immutable. It means that you cannot change its properties after initialized.
To make a property mutable you can use var.
For example:
val housePost = HousePost() // This will use all the default value
housePost.expandable = true // Val cannot be reassigned
To make expandable mutable use var like so:
data class HousePost(
.
.
.
var expandable: Boolean = false
)
val housePost = HousePost()
housePost.expandable = true // Can be reassigned
Edit
You got the error(No setter/field for class found error) because you mark the class property private. You can simply fix it by removing private, the constructor, getters and setters in your current class.
There are other ways to define a property in a class. You will get to know how to use them as you learn.
class HousePost {
var uid: String = ""
var postImage: String = ""
var rent: String = ""
var description: String = ""
var publisher: String = ""
var location: String = ""
var postId: String? = ""
var rooms: String = ""
var caption: String = ""
var dateTime: String = ""
var expandable: Boolean = false
}
Or this:
class HousePost (
var uid: String = ""
var postImage: String = ""
var rent: String = ""
var description: String = ""
var publisher: String = ""
var location: String = ""
var postId: String? = ""
var rooms: String = ""
var caption: String = ""
var dateTime: String = ""
var expandable: Boolean = false
)
You just simple do this. Remove the functions, it's not usable
class HousePost {
private var uid: String = ""
private var postImage: String = ""
private var rent: String = ""
private var description: String = ""
private var publisher: String = ""
private var location: String = ""
private var postId: String? = ""
private var rooms: String = ""
private var caption: String = ""
private var dateTime: String = ""
var expandable: Boolean = false
constructor()
constructor(uid: String,
postImage: String,
rent: String,
description: String,
location: String,
postId: String,
publisher: String,
rooms: String,
caption: String,
dateTime: String) {
this.uid = uid
this.postImage = postImage
this.rent = rent
this.description = description
this.location = location
this.postId = postId
this.publisher = publisher
this.rooms = rooms
this.caption = caption
this.dateTime = dateTime
this.expandable = false
}
}
Kotlin provides default getters and setters for properties, you don't have to manually define them.
In Kotlin
var data: String = ""
is equivalent as
var data: String = ""
get() = field
set(value) {
field = value
}
because Kotlin compiler generates it for you. But if you only want to make your getter public but not setter, then you can override setter
var data: String = ""
private set
You can do the same for the getter too.
This class is supposed to model data from my database. Is that the
correct way in Kotlin?
No, that is not the correct way to define a model class in Kotlin. Kotlin provides data classes, whose main function is to hold data. Data class primary constructor needs at least one parameter.
So, your model class can be refactored like this
data class HousePost(
var uid: String = "",
var postImage: String = "",
var rent: String = "",
var description: String = "",
var publisher: String = "",
var location: String = "",
var postId: String? = "",
var rooms: String = "",
var caption: String = "",
var dateTime: String = "",
var expandable: Boolean = false
)
In any case, if you need only private setters for any field, you can make that constructor property private, and then make a public property that delegates to this private field.
data class HousePost(
private var _uid: String = "",
var postImage: String = "",
var rent: String = "",
var description: String = "",
var publisher: String = "",
var location: String = "",
var postId: String? = "",
var rooms: String = "",
var caption: String = "",
var dateTime: String = "",
var expandable: Boolean = false
) {
val uid: String get() = _uid
}

Handle dynamic response

How to fetch below dynamic JSON response using Retrofit2 in Kotlin/Java?
Sample JSON response where dates & currency data is dynamic
{
"rates":
{
"2018-01-22":
{
"CAD":1.2476509519,
"HKD":7.8183675137,
"HUF":253.0026962987,
"EUR":0.8095854922
},
"2018-01-09":
{
"CAD":1.2476509519,
"HKD":7.8183675137,
"HUF":253.0026962987
},
"2018-01-24":
{
"CAD":1.2476509519,
"HKD":7.8183675137,
"HUF":253.0026962987,
"RUB":56.324886658,
"KRW":1064.8720854922
}
}
}
I have created model classes like this:
data class GetHistoryData(
#SerializedName("rates")
var rates: Any,
)
data class Exchange(
var date: String? = "",
var exchangeCurrencyList: ArrayList<ExchangeCurrency> = ArrayList()
)
data class ExchangeCurrency(
var exchangeCurrency: String,
var exchangeValue: Double
)
I am fetching like this below, where I have iterate each JSON-object manually,
val jsonObject = Gson().fromJson(
response.data!!.rates.toString(),
JsonObject::class.java
)
jsonObject?.keySet()?.forEach { _ ->
val exchangeDatesList = ArrayList<Exchange>()
val iterator: Iterator<String> = jsonObject.keySet().iterator()
while (iterator.hasNext()) {
val dates = Exchange()
val dateKey = iterator.next()
dates.date = dateKey
val currencyObject = jsonObject.getAsJsonObject(dateKey)
val dateIterator: Iterator<String> =
currencyObject.keySet().iterator()
val exchangeCurrencyList = ArrayList<ExchangeCurrency>()
while (dateIterator.hasNext()) {
val currencyKey = dateIterator.next()
val exchangeValue = currencyObject.get(currencyKey)
val exchangeCurrency = ExchangeCurrency()
exchangeCurrency.exchangeCurrency = currencyKey
exchangeCurrency.exchangeValue =
exchangeValue.toString().toDouble()
exchangeCurrencyList.add(exchangeCurrency)
}
dates.exchangeCurrencyList = exchangeCurrencyList
exchangeDatesList.add(dates)
Is there any another approach instead for above?

How to deserialize nested class with Gson in Kotlin?

I have json as in below, I'm really new on kotlin and i tried all examples but cannot set my nested class values when i convert to json
Here my json
{"Init":{"MOP":[{"Id":"1","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXB","TerminalId":"'P400Plus-275008565'","IP":"'192.168.1.15'","Currency":"EUR"},{"Id":"2","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXF","TerminalId":"'P400Plus-275008565'","IP":"'10.0.0.0:901'","Currency":"EUR"}]}}
Here my POJO
class Root {
#JsonProperty("Init")
var init: Init? = null
}
class MOP {
#JsonProperty("Id")
var id: String? = null
#JsonProperty("Type")
var type: String? = null
#JsonProperty("ProtocolVersion")
var protocolVersion: String? = null
#JsonProperty("MopCode")
var mopCode: String? = null
#JsonProperty("TerminalId")
var terminalId: String? = null
#JsonProperty("IP")
var ip: String? = null
#JsonProperty("Currency")
var currency: String? = null
}
class Init {
#JsonProperty("MOP")
var mop: List<MOP>? = null
}
Here my trial
val root: TestClass.Root = gson.fromJson(receiveString,TestClass.Root::class.java)
val initList = HashMap<String?,String?>()
if (root.init != null){
val mopList = root.init!!.mop
if (mopList != null) {
for (item in mopList){
initList.put(item.mopCode,item.id)
}
}
}
Always root.init and root.init.mop are null
What you can suggest me?
Thanks
Your Json construction has different tree.
You should use following structure:
data class Root (
#SerializedName("Init") val init : Init
)
data class Init (
#SerializedName("MOP") val mOP : List<MOP>
)
data class MOP (
#SerializedName("Id") val id : Int,
#SerializedName("Type") val type : Int,
#SerializedName("ProtocolVersion") val protocolVersion : Double,
#SerializedName("MopCode") val mopCode : String,
#SerializedName("TerminalId") val terminalId : String,
#SerializedName("IP") val iP : String,
#SerializedName("Currency") val currency : String
)
And you can parse just with:
Gson().fromJson(data,Root::class.java)
Also if you are using Gson, you should use SerializedName instead JsonProperty.

How to show Realm Data base results to an edit text?

so I'm new to realm data base and I'm trying to show the data that the user wrote throw an Edit text and show it in a Textview..
My realm class
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmClass
#RealmClass
open class GoodStudents : RealmObject(){
#PrimaryKey
var id: Long = 0
var name : String? = null
var grade : Int? = null
}
Main activity code
Realm.init(this)
val convig = RealmConfiguration.Builder()
.name("GoodStudents").build()
val realm = Realm.getInstance(convig)
realm.beginTransaction()
count = realm.where(GoodStudents::class.java).findAll().size
val goodStudents = realm.createObject(GoodStudents::class.java, count+1)
goodStudents.name = name.text.toString()
goodStudents.grade
realm.commitTransaction()
val readData = realm.where(GoodStudents::class.java).findAll()
saveButton.setOnClickListener {
Toast.makeText(this,"Data is saved", Toast.LENGTH_LONG).show()
var text = text.text
readData.forEach { save ->
save.name = text as String?
}
}
P.C. Java code is acceptable..
so I found out that writing this code will work
saveButton.setOnClickListener {
val convig = RealmConfiguration.Builder()
.name("GoodStudents").build()
val realm = Realm.getInstance(convig)
realm.beginTransaction()
count = realm.where(GoodStudents::class.java).findAll().size
val goodStudents = realm.createObject(GoodStudents::class.java, count+1)
goodStudents.name = name.text.toString()
goodStudents.grade = grade.text.toString().toInt()
val readData = realm.where(GoodStudents::class.java).findAll()
readData.forEach { save ->
text.text = "" + save.name + ": " + goodStudents.grade
}
realm.commitTransaction()
}

Categories