Search code examples
androidfunctionandroid-activitykotlinbuttonclick

Kotlin- Function runs after next lines ended


Updated- The code in the question works now

I'm trying to run a function after clicking on a button. The function updates an array and I want to run the next lines (The next lines transfer me to another activity) if the array isn't empty.

I tried to open the new activity within the filterPlaces function but with no success, startActivity and Intent don't work.

This is the function that updates the array:

var places = ArrayList<Place>() //Global place array
class MainActivity : AppCompatActivity() {

    fun filterPlaces(types: ArrayList<String>, foods: ArrayList<String>, maxPrice: Int, maxProximity: Int) {
        var typesList = types
        val foodList = foods
        if (types.isEmpty()) {
            typesList = arrayListOf("Restaurant", "Hangouts")
            if (foods.isEmpty()) {
                foodList.add("Pizza")
            }
        }
        val db = FirebaseFirestore.getInstance()
        db.collection("places").get().addOnSuccessListener { result ->
            for (document in result) {
                val typeMatches = document.data["Type"].toString() in typesList
                val foodMatches = document.data["Food"].toString() in foodList
                var price = 0
                when (document.data["Price"].toString()) {
                    "Very cheap" -> price = 0
                    "Cheap" -> price = 1
                    "Average" -> price = 2
                    "Far" -> price = 3
                    "Very far" -> price = 4
                }
                val priceMatches = price <= maxPrice
                var proximity = 0
                when (document.data["Proximity"].toString()) {
                    "Very close" -> proximity = 0
                    "Close" -> proximity = 1
                    "Far" -> proximity = 2
                    "Very far" -> proximity = 3
                }
                val proximityMatches = proximity <= maxProximity
                if (typeMatches and foodMatches and priceMatches and proximityMatches) {
                    val place = Place(
                        document.data["Place"].toString(),
                        document.data["Type"].toString(),
                        document.data["Food"].toString(),
                        document.data["Price"].toString(),
                        document.data["Proximity"].toString()
                    )
                    places.add(place)
                    Log.d("name", "Place added successfully")
                }
            }

            //Openning the results activity
            if (places.isNotEmpty()) {
                val i = Intent(this, RelevantPlaces::class.java)
                val b = Bundle()
                b.putParcelableArrayList("places", places)
                i.putExtra("bundle", b)
                startActivity(i)
            }
        }
            .addOnFailureListener { exception ->
                Log.d("name", "Error getting documents.")
            }
    }

This is the on click function:

fun onSortFilterClicked(view: View) {
        if (places.isEmpty()) filterPlaces(types, foods, priceRange.progress, proximityRange.progress)
    }

I want to run filterPlaces first, update the places array while I run it, and only than check if the array is still empty and if not open the new activity. What actually happens is that it calls the filterPlaces but doesn't do it, instead it checks the places array (The if condition in the code) and only than goes into filterPlaces and run what's in it, resulted in me need to press twice on the button and only than the array has values. I'm running this on Android Studio and I'm new at this Kotlin world and android developing in general.

Is there a solution for this? Either open the activity within the function or make the function run first?


Solution

  • What is happening?

    An asynchronous request is made in filterPlaces, this is why the method itself returns immediately and passes control to the next code block.

    How to fix this?

    Move your code starting another Activity into the scope of your success listener. A better approach is to place this code into a separate method and just call it as needed.