I am wondering whether it's possible to ensure that a value doesn't go below 0 and not above 5 in the userManager (or Datastore and equivalent) class. If not, then what should I do?
class userManager(context: Context) {
private val datastore = context.datastore
companion object {
val NUMBER_OF_LIVES_KEY = intPreferencesKey("number_of_lives")
}
suspend fun setNumberOfLives(numberOfLives: Int){
datastore.edit {
it[NUMBER_OF_LIVES_KEY] = numberOfLives
}
}
val getNumberOfLives: Flow<Int> = datastore.data.map {
if(it[NUMBER_OF_LIVES_KEY]!! > 5){
it[NUMBER_OF_LIVES_KEY] == 5
}
else if(it[NUMBER_OF_LIVES_KEY]!! < 0){
it[NUMBER_OF_LIVES_KEY] == 0
}
it[NUMBER_OF_LIVES_KEY] ?: 5
}
}
I have attempted the if statements and it gave me a "java.lang.NullPointerException" error message.
https://kotlinlang.org/docs/null-safety.html#the-operator describes it pretty well what happens when you use
!!:Where NPE stands for
NullPointerException, the error that you experience.The solution is easy: If you don't want your code to abort with such an exception, remove the
!!. That way the compiler will prevent you from compiling the erroneous code in the first place and forces you to fix it before you run it.The underlying problem is that the property you try to access does not exist. That is perfectly normal if the app was freshly installed or the user wiped all data. What you want to do instead is handle that situation gracefully by supplying a default value in that case. You actually do that already in your last line of code, but that's too late if you want to work with the value beforehand.
Now there is the other problem that your getter actually also saves data in some cases. Instead, I would suggest that you move everything that changes the preference value into the setter method:
That could be drastically simplified though:
Now your getter only retrieves the preference value and handles the case when it doesn't exist:
This way the code is more concise and less error prone.