Challenge: Minimum Strength

Here is my solution, any feedback is highly appreciated:

private fun updateCharacterFromWeb() {
    GlobalScope.launch(Dispatchers.Main) {
        characterData = fetchCharacterDataAsync().await()
        characterData.str.toInt().let {
            when {
                it < 10 -> updateCharacterFromWeb()
                else -> displayCharacterData()
            }
        }
    }
}

I haven’t traced the threads all the way through, but I worry about making the recursive call by continuing to launch new coroutines.

My solution is similar, but puts a loop inside the launch() routine instead of the recursive call back to the function.

private fun fetchCharacterFromAPIAsync() = CoroutineScope(Dispatchers.Main).launch {
    try {
        // display the "Generating Character" message while blocking call executes
        characterData = CharacterGenerator.placeHolderCharacter()
        displayCharacterData()

        do {
            // fetchCharacterData() is a suspend function - it is a blocking call
            characterData = fetchCharacterDataBlocking()    // perform the API call
            // code will continue when blocking call completes
        } while (characterData.str.toInt() < 10)

        Log.d(LOG_TAG, "fetchCharacterFromAPIAsync() received valid character")

        // display the network queried character
        displayCharacterData()
    } finally {
        Log.d(LOG_TAG, "fetchCharacterFromAPIAsync() finally block")
    }
}

private suspend fun fetchCharacterDataBlocking() = withContext(Dispatchers.IO) {
    val apiData = URL(CHARACTER_DATA_API).readText()
    CharacterGenerator.fromApiData(apiData)
}