Following is my code
var items : MutableList<Any> = arrayListOf()
items.add(TeacherDetails(it?.photo,it?.firstName,it?.lastName,it?.level))
items.add(TeacherBio(it?.bio))
items.add(TitleAccreditations(getString(R.string.acreditations)))
items.add(SessionsTitle(it?.firstName + getString(R.string.apostrophe) + getString(
R.string.sessions)))
items.addAll(listOf(it?.classes ?: arrayListOf()))
items.add(IntroVideo(it?.introVideo))
items.addAll(it?.teachingAccreditations?.split("\n")?.map { Accreditation(
it
) }?: emptyList())
Issue is at following line it is adding entire list as object instead of individual item.
items.addAll(listOf(it?.classes ?: arrayListOf()))
Following is my model
data class Teacher(
#field:SerializedName("firstName")
val firstName: String? = null,
#field:SerializedName("lastName")
val lastName: String? = null,
#field:SerializedName("teacherId")
val teacherId: String? = null,
#field:SerializedName("introVideo")
val introVideo: String? = null,
#field:SerializedName("level")
val level: String? = null,
#field:SerializedName("teachingAccreditations")
val teachingAccreditations: String? = null,
#field:SerializedName("classes")
val classes: List<ClassesItem?>? = null,
#field:SerializedName("photo")
val photo: String? = null,
#field:SerializedName("bio")
val bio: String? = null
)
I guess because your type of list is Any, it will consider adding list instance also as an object, so instead it as listOf() just add directly
items.addAll(it?.classes?.filterNotNull()?: arrayListOf())
Related
I am trying to parse the following api endpoint.
http://ergast.com/api/f1/current/driverStandings.json
I'm confused about the structure of the json response. specificaly i cant find a way to display driver's name and last name in a recycler view.
i've managed to display data from another json file of the same endpoint, but not from this one.
spent 2-3 days researching and googling.
There is a Plugin in Android Studio called JSON to Kotlin Class. You just have to copy the JSON reponse and paste it there in the plugin and it will generate the necessary classes for you, so you can visualize it more clearly. So what you would end up is:
data class ExampleJson2KtKotlin (
#SerializedName("MRData" ) var MRData : MRData? = MRData()
)
data class MRData (
#SerializedName("xmlns" ) var xmlns : String? = null,
#SerializedName("series" ) var series : String? = null,
#SerializedName("url" ) var url : String? = null,
#SerializedName("limit" ) var limit : String? = null,
#SerializedName("offset" ) var offset : String? = null,
#SerializedName("total" ) var total : String? = null,
#SerializedName("StandingsTable" ) var StandingsTable : StandingsTable? = StandingsTable()
)
data class StandingsTable (
#SerializedName("season" ) var season : String? = null,
#SerializedName("StandingsLists" ) var StandingsLists : ArrayList<StandingsLists> = arrayListOf()
)
data class StandingsLists (
#SerializedName("season" ) var season : String? = null,
#SerializedName("round" ) var round : String? = null,
#SerializedName("DriverStandings" ) var DriverStandings : ArrayList<DriverStandings> = arrayListOf()
)
data class DriverStandings (
#SerializedName("position" ) var position : String? = null,
#SerializedName("positionText" ) var positionText : String? = null,
#SerializedName("points" ) var points : String? = null,
#SerializedName("wins" ) var wins : String? = null,
#SerializedName("Driver" ) var Driver : Driver? = Driver(),
#SerializedName("Constructors" ) var Constructors : ArrayList<Constructors> = arrayListOf()
)
data class Driver (
#SerializedName("driverId" ) var driverId : String? = null,
#SerializedName("permanentNumber" ) var permanentNumber : String? = null,
#SerializedName("code" ) var code : String? = null,
#SerializedName("url" ) var url : String? = null,
#SerializedName("givenName" ) var givenName : String? = null,
#SerializedName("familyName" ) var familyName : String? = null,
#SerializedName("dateOfBirth" ) var dateOfBirth : String? = null,
#SerializedName("nationality" ) var nationality : String? = null
)
data class Constructors (
#SerializedName("constructorId" ) var constructorId : String? = null,
#SerializedName("url" ) var url : String? = null,
#SerializedName("name" ) var name : String? = null,
#SerializedName("nationality" ) var nationality : String? = null
)
And then your response will become like this if you use retrofit
interface RetrofitInterface {
#GET("example-endpoint")
suspend fun getDataList(): MRData
}
Then you just collect the data in your ViewModel and display it in the RecycleView.
The basic parsing can be achieved by this way.
val mrDataJsonObj = response.getJSONObject("MRData")
val standingTableObj = mrDataJsonObj.getJSONObject("StandingsTable")
val standingListJsonArray = standingTableObj.getJSONArray("StandingsLists")
for (i in 0 until standingListJsonArray.length()) {
val seasonObj = standingListJsonArray.get(i) as JSONObject
val driverStandingsArray = seasonObj.getJSONArray("DriverStandings")
for ( j in 0 until driverStandingsArray.length()){
val driverStandingObj = driverStandingsArray.get(j) as JSONObject
val driverObj = driverStandingObj.getJSONObject("Driver")
// Get All the Driver Attributes from driverObj
if(driverObj.has("givenName"))
Log.d(TAG, "dummyData: Given Name : " +driverObj.getString("givenName"))
if(driverObj.has("familyName"))
Log.d(TAG, "dummyData: Family Name " +driverObj.getString("familyName"))
}
}
Im trying to serialize a Json file. But there's many variables with the type 'Any', and the #Serializable annotation is not working with this type.
I've tried to do exactly like the answer in this question:
Kotlin serialization: Serializer has not been found for type 'UUID'
But the problem is that there is no "from string()" function for the type 'Any'.
Is there a solution for this?
Edit:
This is some of the data classes
#Serializable
data class ApiResponse(
val data:List<ApiResponseItem> = emptyList()
)
#Serializable
data class ApiResponseItem(
#SerializedName("cards")
val cards: List<Any>? = null,
#SerializedName("country_id")
val country_id: String? = null,
#SerializedName("country_logo")
val country_logo: String? = null,
#SerializedName("country_name")
val country_name: String? = null,
#SerializedName("fk_stage_key")
val fk_stage_key: String? = null,
#SerializedName("goalscorer")
val goalscorer: List<Any>? = null,
#SerializedName("league_id")
val league_id: String? = null,
#SerializedName("league_logo")
val league_logo: String? = null,
#SerializedName("league_name")
val league_name: String? = null,
#SerializedName("league_year")
val league_year: String? = null,
#SerializedName("lineup")
val lineup: Lineup? = null,
#SerializedName("match_awayteam_extra_score")
val match_awayteam_extra_score: String? = null,
#SerializedName("match_awayteam_ft_score")
val match_awayteam_ft_score: String? = null,
#SerializedName("match_awayteam_halftime_score")
val match_awayteam_halftime_score: String? = null,
#SerializedName("match_awayteam_id")
val match_awayteam_id: String? = null,
#SerializedName("match_awayteam_name")
val match_awayteam_name: String? = null,
#SerializedName("match_awayteam_penalty_score")
val match_awayteam_penalty_score: String? = null,
#SerializedName("match_awayteam_score")
val match_awayteam_score: String? = null,
#SerializedName("match_awayteam_system")
val match_awayteam_system: String? = null,
#SerializedName("match_date")
val match_date: String? = null,
#SerializedName("match_hometeam_extra_score")
val match_hometeam_extra_score: String? = null,
#SerializedName("match_hometeam_ft_score")
val match_hometeam_ft_score: String? = null,
#SerializedName(" match_hometeam_halftime_score")
val match_hometeam_halftime_score: String? = null,
#SerializedName("match_hometeam_id")
val match_hometeam_id: String? = null,
#SerializedName("match_hometeam_name")
val match_hometeam_name: String? = null,
#SerializedName("match_hometeam_penalty_score")
val match_hometeam_penalty_score: String? = null,
#SerializedName("match_hometeam_score")
val match_hometeam_score: String? = null,
#SerializedName("match_hometeam_system")
val match_hometeam_system: String? = null,
#SerializedName("match_id")
val match_id: String? = null,
#SerializedName("match_live")
val match_live: String? = null,
#SerializedName("match_referee")
val match_referee: String? = null,
#SerializedName(" match_round")
val match_round: String? = null,
#SerializedName("match_stadium")
val match_stadium: String? = null,
#SerializedName("mmatch_status")
val match_status: String? = null,
#SerializedName("match_time")
val match_time: String? = null,
#SerializedName("stage_name")
val stage_name: String? = null,
#SerializedName("statistics_1half")
val statistics_1half: List<Any>? = null,
#SerializedName("substitutions")
val substitutions: Substitutions? = null,
#SerializedName("team_away_badge")
val team_away_badge: String? = null,
#SerializedName("team_home_badge")
val team_home_badge: String? = null
)
Simply put, you can't make a class Serializable when it has fields of type Any. It's simply not possible because Any can quite literally be anything, including classes that are not Serializable. Try defining them more specific. I can assume that
val cards: List<Any>? = null,
is actually maybe
val cards: List<Card>? = null,
As long as you make sure that the types you put there are Serializable it should work
I have a dataclass:
data class MoviesInSeries(
val originalMovieName: String,
// If there's no value of parameter, assign it as null
val movieInSeries1Name: String? = null,
val movieInSeries1Date: String? = null,
val movieInSeries1Rating: String? = null,
val movieInSeries1Pic: Int? = null,
val movieInSeries2Name: String? = null,
val movieInSeries2Date: String? = null,
val movieInSeries2Rating: String? = null,
val movieInSeries2Pic: Int? = null,
)
I've created two objects of it.
fun getRestOfSeriesMovies(): ArrayList<MoviesInSeries> {
val movieList = ArrayList<MoviesInSeries>()
val s_gi_joe = MoviesInSeries("G.I. Joe: Retaliation", "G.I. Joe: The Rise of Cobra",
"2009","Pg-13", R.drawable.gijtsofmp)
movieList.add(s_gi_joe)
val s_gi_joe2 = MoviesInSeries("G.I. Joe: Retaliation2", "G.I. Joe: The Rise of Cobra",
"2009","Pg-13", R.drawable.gijtsofmp)
movieList.add(s_gi_joe)
return movieList
}
Now I want to create an array list of the originalMovieName member. I'll later use that to check if a certain string is in it. How would I do that?
there's a lot of weird things happening in your model class :
1-
checkIFMovieNameExist(getRestOfSeriesMovies())
fun checkIFMovieNameExist(list: List<MoviesInSeries>,value:String): MoviesInSeries? {
return list.find { it.originalMovieName == value }
}
2-from time of creation:
data class MoviesInSeries(
val originalMovieName: String,
// If there's no value of parameter, assign it as null
val movieInSeries1Name: String? = null,
val movieInSeries1Date: String? = null,
val movieInSeries1Rating: String? = null,
val movieInSeries1Pic: Int? = null,
val movieInSeries2Name: String? = null,
val movieInSeries2Date: String? = null,
val movieInSeries2Rating: String? = null,
val movieInSeries2Pic: Int? = null,
){
init {
names.add(originalMovieName)
}
companion object {
private val names: MutableList<String> = mutableListOf()
fun getMoviesNames():List<String>{
return names
}
}
}
then you can check if a name exist in names list in any place in the code
MoviesInSeries("sd1")
MoviesInSeries("sd2")
MoviesInSeries("sd3")
MoviesInSeries("sd4")
println(MoviesInSeries. getMoviesNames().contains("sd1"))
I have a doubt about creating tables for my network response.
My network response will be like:
data class ProductsList(
val next: String? = null,
val perPage: Int? = null,
val previous: String? = null,
val count: Int? = null,
val results: Results? = null
)
data class Results(
val prices: List<PricesItem?>? = null,
val products: List<ProductsItem?>? = null
)
data class ProductsItem(
val image: String? = null,
val content: List<Int?>? = null,
val prices: List<Int?>? = null
)
I'm confused the I should have one table or many tables. I'm beginner to room and SQL so if you have any resource to learn more about the room and data handling that will be very helpful for me.
Thanks in advance.
I have a scenario. I have created a data class in Kotlin like this:
data class AgentDetails(
val mobileNo: String,
val Name: String,
val Email: String,
val Password: String,
val Occupation: String,
val pincode: String,
val usertype: String,
val profilepic: String,
val AccountStatus: String
)
I want to send different type of objects of this data class to a web service:
1st object example:
val agentDetails = AgentDetails(mobileNo = mobileNumberText.text.toString(),
Name = userNameText.text.toString(),
Email = emailIdText.text.toString(),
Password = HashUtils.sha1(passwordText.text.toString()),
Occupation = item,
pincode = pinCodeText.text.toString(),
usertype = "Agent",
profilepic = "null", AccountStatus = "pending")
In 2nd object I only want to send mobile number. I dont wanna include any other field. Something like this:
val agentDetails = AgentDetails(mobileNo = mobileNumberText.text.toString())
And in 3rd object I only wanna send email id. Instead of creating multiple data classes. Can I use the same data class for multiple implementations?
Personally, I'd define three objects because they represent three different concepts (or projections of a concept). But if you make your properties nullable and provide a default value of null, you can get away with creating them as you want...
data class AgentDetails(
val mobileNo: String? = null,
val name: String? = null,
val email: String? = null,
val password: String? = null,
val occupation: String? = null,
val pincode: String? = null,
val usertype: String? = null,
val profilepic: String? = null,
val accountStatus: String? = null
)
Note: I've changed some of your property names to camelCase, as is the proper convention. And these all work fine:
AgentDetails(mobileNo = mobileNumberText.text.toString())
AgentDetails(email = "foo#example.com")
AgentDetails(name = "Foo", password = "Bar")
All of the other fields not provided will be null, and the types will be nullable, so you'll have to guard against that. Otherwise, I'd define three data classes for this.
Another solution would be to consider a sealed class structure:
sealed class AgentDetails
data class AgentByName(val name: String) : AgentDetails()
data class AgentByEmail(val email: String): AgentDetails()
// etc..
And then use it in a when expression:
fun doSomethingWithAgents(agentDetails: AgentDetails) {
when (agentDetails) {
is AgentByName -> // Do something
is AgentByEmail -> // Do Something
}
}
The easiest way is to make the fields nullable and provide default values:
data class AgentDetails(
val mobileNo: String? = null,
val Name: String? = null,
val Email: String? = null,
val Password: String? = null,
val Occupation: String? = null,
val pincode: String? = null,
val usertype: String? = null,
val profilepic: String? = null,
val AccountStatus: String? = null
)