Show JSON Data in Kotlin - android

I would like to place JSON Data inside the material card widget (see image). Before asking, I also did my own research - however, I can't seem to fix it. Everything that I try ends up in even more error codes.
For now, I'm just trying to get the right output by using Log. Later on, I want to place the JSON data inside the cards. However, that's a problem for later.
Hopefully providing you with enough information; this is the location of JSON file:
Code
import getJsonDataFromAsset
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
#Serializable
data class Item (
val id: Int? = null,
val image: String? = null,
val title: String? = null,
val description: String? = null,
val longDescription: String? = null,
val company: String? = null,
val price: Int? = null,
val duration: Int? = null,
val valued: String? = null
)
private var json = Json {
ignoreUnknownKeys = true
}
val jsonFileString = getJsonDataFromAsset(applicationContext, "activities.json")
val obj = json.decodeFromString<Item>(jsonFileString.toString())
if (jsonFileString != null){
Log.i("data", jsonFileString)
Log.i("obj.entertainment", obj.description.toString())
} else {
Log.e("catch", "Error")
}
Beginning of JSON-File.
I want to access the objects/properties inside the items array.
{
"items" : [
{
"id": 0,
"image": "img/glowgolf.png",
"title": "Glowgolf",
"description": "Activity description",
"longDescription": "Activity description descriptionActivity description descriptionActivity description descriptionActivity description description",
"company": "Friend",
"price": 25,
"duration": 2,
"valued": ""
}
...
Output
I/obj.entertainment: null

After trying a few more times, the following code showed the desired output.
Log.i("obj.entertainment", obj.items[0].title.toString())
Output: Glowgolf
To place it into your view add val titleActivityCard = findViewById<TextView>(R.id.titleFirstCard) and titleActivityCard.text = obj.items[0].toString()
Better answers are always welcome, but hereby the question is closed.

Related

Json String from websocket to dataClass

I need to convert some json string that im reciving from okhttp websocket binance connection to data class to manipulate the data
override fun onMessage(webSocket: WebSocket, text: String) {
//convert string "text" to dataclass
Log.d("Websocket", text)
}
Log: D/Websocket: {"e":"24hrTicker","E":1661477897574,"s":"BNBUSDT","p":"0.30000000","P":"0.100","w":"301.82156206","x":"298.60000000","c":"298.90000000","Q":"1.06900000","b":"298.80000000","B":"353.26400000","a":"298.90000000","A":"358.58100000","o":"298.60000000","h":"307.50000000","l":"296.00000000","v":"412516.01400000","q":"124506227.71920000","O":1661391497474,"C":1661477897474,"F":581001589,"L":581229754,"n":228166}
String recived:
{
"e": "24hrTicker", // Event type
"E": 123456789, // Event time
"s": "BNBBTC", // Symbol
"p": "0.0015", // Price change
"P": "250.00", // Price change percent
"w": "0.0018", // Weighted average price
"x": "0.0009", // First trade(F)-1 price (first trade before the 24hr rolling window)
"c": "0.0025", // Last price
"Q": "10", // Last quantity
"b": "0.0024", // Best bid price
"B": "10", // Best bid quantity
"a": "0.0026", // Best ask price
"A": "100", // Best ask quantity
"o": "0.0010", // Open price
"h": "0.0025", // High price
"l": "0.0010", // Low price
"v": "10000", // Total traded base asset volume
"q": "18", // Total traded quote asset volume
"O": 0, // Statistics open time
"C": 86400000, // Statistics close time
"F": 0, // First trade ID
"L": 18150, // Last trade Id
"n": 18151 // Total number of trades
}
which is the best implementation? Thanks!
First of all,you need to have a protocol with server end, and settle down all the message IDL models.
Then you can use some tools to transfer IDL to Java Model.
as for json to model, you can use https://www.jsonschema2pojo.org/
But I suggest you use protobuf. which is more effective than json. https://square.github.io/wire/
Gson dependency
implementation 'com.google.code.gson:gson:2.9.1'
Data class of your json is like below
import com.google.gson.annotations.SerializedName
data class Websocket(
#SerializedName("e" ) var e : String? = null,
#SerializedName("E" ) var E : Int? = null,
#SerializedName("s" ) var s : String? = null,
#SerializedName("p" ) var p : String? = null,
#SerializedName("P" ) var P : String? = null,
#SerializedName("w" ) var w : String? = null,
#SerializedName("x" ) var x : String? = null,
#SerializedName("c" ) var c : String? = null,
#SerializedName("Q" ) var Q : String? = null,
#SerializedName("b" ) var b : String? = null,
#SerializedName("B" ) var B : String? = null,
#SerializedName("a" ) var a : String? = null,
#SerializedName("A" ) var A : String? = null,
#SerializedName("o" ) var o : String? = null,
#SerializedName("h" ) var h : String? = null,
#SerializedName("l" ) var l : String? = null,
#SerializedName("v" ) var v : String? = null,
#SerializedName("q" ) var q : String? = null,
#SerializedName("O" ) var O : Int? = null,
#SerializedName("C" ) var C : Int? = null,
#SerializedName("F" ) var F : Int? = null,
#SerializedName("L" ) var L : Int? = null,
#SerializedName("n" ) var n : Int? = null
)
convert your json string to data model
var gson = Gson()
val modelClassOfJsonString: Websocket = gson.fromJson("YOUR JSON STRING", Websocket::class.java)
use modelClassOfJsonString
and if you went to convert model class to json string use
var stringOfmodel : String = gson.toJson(modelClassOfJsonString)

How do you properly model a JSON map in android

I'm trying to pass a map from Firestore into a data class but I'm getting null instead of the data
This is how my data is accessed:
firestoreDb = FirebaseFirestore.getInstance()
val postsRef = firestoreDb
.collection("posts")
.limit(20)
.orderBy("creation_time_ms", Query.Direction.DESCENDING)
.orderBy("date", Query.Direction.DESCENDING)
postsRef.addSnapshotListener { snapshot, exception ->
if (exception != null || snapshot == null) {
Log.e(TAG,"Exception when querying post", exception )
return#addSnapshotListener
}
val postList = snapshot.toObjects(HousePost::class.java)
for (post in postList) {
Log.i(TAG, "Posts $post")
}
}
My model for the data
data class HousePost (
#get:PropertyName("image_url") #set:PropertyName("image_url") var postImage: String = "",
var rent: String = "",
var description: String = "",
#get:PropertyName("creation_time_ms") #set:PropertyName("creation_time_ms") var creationTimeMs: Long = 0L,
var location: String = "",
#get:PropertyName("post_id") #set:PropertyName("post_id")var postId: String? = "",
var rooms: String = "",
var caption: String = "",
var date: String = "",
var owner: Owner? = null
)
My Owner model class
class Owner(
var uid: String = "",
var username: String = "",
var email: String = "",
#get:PropertyName("profile_image") #set:PropertyName("profile_image") var profileImage: String = "",
#get:PropertyName("user_type") #set:PropertyName("user_type")var usertype: String = "owner"
)
Here is my firestore data I know some fields are an empty string but that shouldn't output null.
This is the result from logcat
2022-05-03 11:42:12.313 6581-6581/com.example.moveapplication I/MainActivity: Posts HousePost(postImage=https://firebasestorage.googleapis.com/v0/b/moveapplicationdb.appspot.com/o/Post%20Pictures%2Fian-dooley-_-JR5TxKNSo-unsplash.jpg?alt=media&token=6721ec57-7602-41ee-b7cd-b8b1838b27fc, rent=15000, description=Along Ngong road we have a studio room for you to rent. Located in a moder =n area with nice infrastrucure, creationTimeMs=1651561930185, location=Lenana, postId=, rooms=studio room, caption=studio room along Ngong road, date=03/05/2022, owner=null)
My index from firestore
Looking at your class definitions, all look fine. You're using the correct annotations. However, when you're using the following query:
val postsRef = firestoreDb
.collection("posts")
.limit(20)
You'll need to know that you have to create an index. It can be manually created inside the Firebase Console or if you are using Android Studio, you'll find a message in the logcat that sounds like this:
FAILED_PRECONDITION: The query requires an index. You can create it here: ...
Simply click on that link or copy and paste the URL into a web browser and your index will be created automatically for you.

com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type Data class object KOTLIN

I have read other comments on this same issue, but none of them has touched on a situation like mine
In mine, below describes how the data is structured
val ref: DatabaseReference? = Firebase.database.getReference("symbols/${alphabets}")
{
"symbols" : {
"alphabets" : {
"a" : {
"available" : true,
"text" : "A",
"timestamp" : 1.512686825309134E9
},
"b" : {
"available" : true,
"text" : "B",
"timestamp" : 1.512687248764272E9
}
"NameOfSymbols" : "group of alphabets"
}
}
}
the list of the data continues, then the string is at the end of the objects
*The reason why mine is showing the error is because it can't convert the string "NameOfSymbols" : "alphabets" to the objects as specified in the data class
So, what can be done about it, I use kotlin
Is there a way I can exclude that part of the children value while I only get the one that is specified in the data class?
Data Class
data class alphabets(
val name: Names,
var NameOfSymbols: String? = null) {
data class Names(
var available: Boolean? = null,
var text: String? = null,
var timestamp: Long? = null) {
}
}
If you are listening to
"symbols/alphabets"
Then the children inside are:
"a" : {
"available" : true,
"text" : "A",
"timestamp" : 1.512686825309134E9
}
That is a Map<String, Any> in this case we can define that Any into a specific data class as you want
data class Names(
val available: Boolean? = null,
val text: String? = null,
val timestamp: Long? = null
)
Then you have that you have to transform your snapshot to:
Map<String, Names>

Parse Mutable Live Data to Array in Kotlin

There is a mutableLiveData Holding 2 array "deal" and "category" I need to parse this both in different adapters.
Is there a way I can convert 1 mutable live data to 2 array and then parse them to two different adapters
Suppose There is MutableVariable Name se
private lateinit var mHomePojo: MutableLiveData<List<HomePojo>>
having parse Json as below
{
"status": 0,
"response": "success",
"category": [
{
"categoryName": "demo",
"categoryDesc": "demo"
},
{
"categoryName": "demo1",
"categoryDesc": "demo"
}
],
"deal": [
{
"dealImg": "https://aiotechnology.in/Aditechweb/upload/153102117.jpg",
"dealDesc": "gd",
"dealStartDate": "2019-10-18",
"dealEndDate": "2019-10-19"
}
]
}
Is there any way to parse private lateinit var mHomePojo: MutableLiveData<List<HomePojo>> to lateinit var mDealModel: MutableLiveData<List<DealModel>> and
lateinit var mCategoryModel: MutableLiveData<List<CategoryModel>>
I am new to MVVM please help
I think Transformations might be able to help you separate your home live data to two separate livedata object with specified properties. below is piece of code for this. (NOTE : not used lateinit var for example)
private val homeLiveData: LiveData<HomePojo> = MutableLiveData<HomePojo>()
//Category Live data
private val categoryPojo = Transformations.map(homeLiveData) {
it.category
}
//Deal live data
private val dealPojo = Transformations.map(homeLiveData) {
it.deal
}
data class HomePojo(
/*-- Other fields --*/
val category: List<CategoryPojo>? = null,
val deal: List<DealPojo>? = null)
data class CategoryPojo(
val categoryName: String? = null,
val categoryDesc: String? = null)
data class DealPojo(
val dealImg: String? = null,
val dealDesc: String? = null,
val dealStartDate: String? = null,
val dealEndDate: String? = null)

Android/Kotlin: GSON doesn't parse correctly some fields JSON

GSON doesn't parse correctly my JSON and returns null for some fields only.
Indeed, I correctly get for every doctor the rpps and code but I have null for lifenId, firstName and lastName.
I have a JSON which is a list of doctor looks like this :
[
{
"lifenId": "238536",
"rpps": "10002732211",
"firstName": "Yolande ",
"lastName": "Couffinhal",
"email": null,
"postalCode": null,
"city": null,
"address": null,
"code": "Médecin Neuro-psychiatrie ",
"phone": null
},
...
]
I'm sure that my JSON is correct because the JSON I receive is exactly the one I post here so these value are not null (for example, I'm not talking about the phone which is null in the JSON)
I tried to parse manually the JSON to get firstName and lastName it works (obviously because I have a good JSON, but I wanted to be sure of that)
There is my data class Doctor :
data class Doctor(var phone: String,
var code: String,
var address: MutableList<String>,
var email: String,
var rpps: String,
var city: String,
var lastName: Any,
var firstName: Any,
var lifenId: String,
var postalCode: String) {
}
My request:
fun getDoctorsByName(name: String, token: String): Single<List<Doctor>> {
val url = "lifen/name/" + name
return repository.getDoctorsByName(url, token).compose(schedulerProvider.getSchedulersForSingle())
}
how I treat the return :
disposable.add(viewModel.getDoctorsByName(search_bar.query.toString(), activity.token)
.doOnError {
Toast.makeText(activity, it.message, Toast.LENGTH_SHORT).show()
}
.subscribe(
{ doctors ->
/*val list = ArrayList<Doctor>()
val doc = Doctor("", "","","","",doctors[0]["lastName"] as String,doctors[0]["firstName"] as String,"","") parse manually here
list.add(doc)
adapter.updateList(list)*/
adapter.updateList(doctors)
Toast.makeText(activity, "LIST COMPLETED", Toast.LENGTH_SHORT).show()
}, Throwable::printStackTrace
)
)
You have firstName and lastName as Any in your data class. Change them to String and you should be good. Also if they are sometimes null mark them as nullable and check when accessing them.
I found the bug, when I create the GSON client, I'm putting a filter as follows:
fun provideGson(): Gson {
return GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create()
}
so I just removed this filter, so that's why on lifenId, firstName and lastName, GSON didn't get these fields.

Categories

Resources