Home > Software engineering >  Variable 'wordlist' must be initialized error in kotlin
Variable 'wordlist' must be initialized error in kotlin

Time:10-27

I 'm trying to fetch data from internet using jsoap in kotlin. I fetched data from internet and I want to assigned it to a property that I declared to use easily again but I got this error. I know it is very simple error but I want to learn bacground of issiue. First of all I declared a property and assigned it to datas from internet in the scope but when I want to use it outside of scope it accours this error. What I don't understand is that I have already assigned the data from the internet to this variable, why does it want to initialize the variable again? and when I define it like this,

var wordList : MutableList<ExtractedData>?=null 

the error goes away, but then the data outside the scope is null or empty in the console. But again, the data in the scop I made fetchdata continues to come properly, there is no problem there again.

My Code

@Composable
fun MostUsedWordScreen(viewModel: MostUsedWordScreenViewModel = hiltViewModel()) {

    var wordList : MutableList<ExtractedData>

    viewModel.fetchData().observe(LocalLifecycleOwner.current, Observer {
        wordList = it
        println("inside wordlist" wordList)
    })

    println("outside wordlist" wordList)

    MostUsedWordItem(wordArray = wordList)


}

My error

Variable 'wordList' must be initialized

CodePudding user response:

You can't use a variable unless it has definitely been already initialized. Let's take a look at your function body:

var wordList : MutableList<ExtractedData>

viewModel.fetchData().observe(LocalLifecycleOwner.current, Observer {
    wordList = it
    println(wordList) //-->here it shows data from internet there is no problem

At this point, the compiler knows that wordList has definitely been initialized, since you assign to it in this block, just a couple of statements above.

})

Now you're outside the block, and at this point the compiler doesn't know whether the above block that assigns to wordList will have been executed or not. If it hasn't been executed, wordList will not be initialized.

println(wordList)//-->but here it wants to be initialized again

Hence you get this error. It doesn't "want to be initialized again" - it may not have been initialized even once.

MostUsedWordItem(wordArray = wordList)

And again here, wordList is being used without having definitely been initialized.

I've just given you the reason for the error message. The solution to your problem is given by Tenfour's comment to your question.

CodePudding user response:

LiveData must be reacted to. It doesn't make sense to copy a value received in the observer into a local variable that is used outside the observer's scope, because the observer will be called after all the other code is already done using the local variable with its initial value.

But since you're using Compose, you can use State to treat LiveData just like a variable. Then it will trigger recomposition when new values arrive. This is effectively similar to how it would look to put all your code inside the Observer block, except that you can call other Composables and it is much cleaner, especially if there are multiple LiveData to work with. Use observeAsState() as a variable delegate to do this:

@Composable
fun MostUsedWordScreen(viewModel: MostUsedWordScreenViewModel = hiltViewModel()) {

    val wordList: List<ExtractedData> by viewModel.fetchData().observeAsState()

    MostUsedWordItem(wordArray = wordList)

}
  • Related