Where is PLANT_ID_SAVED_STATE_KEY set in sunflower app example? - android

I am using the sunflow app example (https://github.com/android/sunflower) as a basis to learn Hilt, Room and many other nice concepts of android coding.
In the PlantDetailViewModel class there is this line:
val plantId: String = savedStateHandle.get<String>(PLANT_ID_SAVED_STATE_KEY)!!.
But I cannot see nowhere in the entire project where PLANT_ID_SAVED_STATE_KEY is set.
am I missing something?
Thanks

It is set, to the string plantId in the PlantDetailViewModel class (at the bottom - line 55) using :-
companion object {
private const val PLANT_ID_SAVED_STATE_KEY = "plantId"
}

Related

Generics in Kotlin Serialization produces compile time error

I am having trouble compiling a Serialization data class that is also a generic. I am very new to Android and Kotlin, but am an experienced iOS/Swift developer (don't hold it against me).
I am trying to set up a generic data class wrapper around a GraphQL Response that can return me either the T generic in a data field, or an error in the error field.
import kotlinx.serialization.Serializable
#Serializable
data class GraphQLResponse<T:Serializable> (
val errors : List<ErrorResponse>? = null,
val data : Map<String, T>? = null
) {
#Serializable
data class Location(
val line: Int? = 0,
val column: Int? = 0,
val sourceName: String? = null
)
#Serializable
data class ErrorResponse(
val locations: List<Location>? = null,
val errorType: String? = null,
val message: String? = null
)
}
Compiling this I get the following error:
java.lang.AssertionError: Couldn't load KotlinClass from /Users/brett/Development/Company/android/app/build/tmp/kotlin-classes/debug/com/company/company/network/GraphQLResponse.class; it may happen because class doesn't have valid Kotlin annotations
And also a bunch of warning around reflection.
Is what I am trying to do possible with Generics and Serialization? Do I need to write my own deserialisation methods ?
Any help and advice would be appreciated.
You need to provide a custom serializer for type T.
check this guide
(BTW, in your code type T shouldn't be Serializable - T:Serializable. It's just annotation)
There is a similar question, check this out.
However, as you can see it may not work well if you use kapt in your project even you provide the serializer.
I found this comment from the serialization repository :
However, due to the mentioned kapt issue, it's impossible for now. Probably, a viable workaround can be to move models and serializers to the separate Gradle module, which is not processed by kapt.
And there are more issues about this problem :
https://github.com/Kotlin/kotlinx.serialization/issues/1148
https://github.com/Kotlin/kotlinx.serialization/issues/685
https://github.com/Kotlin/kotlinx.serialization/issues/1313

Cannot access 'split': it is private in file

I develop an app with Kotlin and got this weird error today in Android Studio, so I tried the same code in InteliJ Idea as well, where I get the same behaviour. I've used the split method so far in my Android project and it worked always like a charm.
This is the code where this behaviour appears:
val rawString = "OK;ABC;34"
val delimited = rawString.split(";",true,0).last()
So today, the compiler says that the split method cannot be reached, because it is private in file. Go figure!
In the code above, I'm trying to get the String "34" into my delimited variable. Are there any restrictions that I'm missing or are there any changes made on this method?
Thanks in advance.
Use like the below, split that you have used is a private function in Strings.kt class
val rawString = "OK;ABC;34"
val delimited = rawString.split(";", ignoreCase = true, limit = 0).last()

Is there better way for handle kotlinx serialization?

I use kotlinx.serialization on Kotlin native project, I a defined Super class for my models and all of the models extends from it.
I defined a function to called toJSON() for serialize variables and fields inside model that all of class models have it.
#Serializable
open class Model {
fun toJSON(): String = JSON.stringify(this);
}
And I created a subclass
class Me : Model() {
var name:String = "Jack";
}
but when I invoke JSON.stringify(this), IDE get a Warning to me:
This declaration is experimental and its usage must be marked with '#kotlinx.serialization.ImplicitReflectionSerializer' or '#UseExperimental(kotlinx.serialization.ImplicitReflectionSerializer::class)'
I paid attention and I used #ImplicitReflectionSerializer annotation while not worked.
Where is my problem?
This is discussed here. It's the particular overload you're using which is still experimental. So your options are either to use the other overload (which takes in a serializer) or to use one of the annotations mentioned in the error message. If you look at the answer to the question I linked (and the comments following it), you'll see it talks about using #UseExperimental and where it should be used.

Problem converting an Array<T> to Observable<Array<T>> using RxJava2

Basically what I am trying is to return an Observable<Array<T>>. I double-checked that getAllCategoriesFromDB() returns Array<Categroies>. categoryDao is a kotlin class.
I tried using this code:
fun getAllCategoriesFromDB(): Observable<Array<Categories>>
{
return categoryDao.selectAllCategories().toObservable()
}
However the returned type is Observable<Categories> instead of Observable<Array<Categories>>
I followed the example from here (scroll down to the repository example code)
My selectAllCategories() looks like this (keep in mind I'm using Room):
#Query("SELECT * FROM Categories")
fun selectAllCategories(): Array<Categories>
Help or advice would be much appreciated since it's the first time I'm working with RxJava2.
I solved it with this code. It might not look as clean or be the best solution but at least it works:
var categories = categoryDao.selectAllCategories()
var observable = Observable.fromArray(categories)

Using JSON.stringify on object without serializer needs to be marked as experimental

Using kotlin plugin 1.3.10 in Android Studio,
when I try to stringify a simple class' object to JSON, it wont compile:
This declaration is experimental and its usage must be marked with '#kotlinx.serialization.ImplicitReflectionSerializer' or '#UseExperimental(kotlinx.serialization.ImplicitReflectionSerializer::class)'
#Serializable data class Data(val a: Int, val b: Int)
val data = Data(1, 2)
val x = JSON.stringify(data)
However, giving a serialiser works:
val x = JSON.stringify(Data.serializer(), data)
I can't see anybody else having this problem, any idea what the problem is? I've set up using serialisation in gradle.build.
I import with:
import kotlinx.serialization.*
import kotlinx.serialization.json.JSON
The overload of StringFormat.stringify which doesn't take in a serializer (SerializationStrategy) is still experimental. If you view its definition (e.g. ctrl+click on it in the IDE) you'll see it looks as follows:
#ImplicitReflectionSerializer
inline fun <reified T : Any> StringFormat.stringify(obj: T): String = stringify(context.getOrDefault(T::class), obj)
Where that ImplicitReflectionSerializer annotation is itself declared in that same file (SerialImplicits.kt):
#Experimental
annotation class ImplicitReflectionSerializer
So because it's still experimental, you need to do exactly as the warning says, i.e. tell the compiler to allow the use of experimental features, by adding an annotation such as #UseExperimental... where you're using it.
Note that the quick example shown on the kotlinx.serialization GitHub repo's main readme shows that you need to pass in a serializer when calling stringify.

Categories

Resources