Trying to update API link based on what the user selects on a spinner

I’m working with an API that gets a list of holidays “https://date.nager.at/api/v3/PublicHolidays/2024/”.

I have a spinner with 5 items that are countries abbreviated. Ideally, when the user selects an item, I need to get that text and append it to the API link (https://date.nager.at/api/v3/PublicHolidays/2024/US), and whenever the user selects a different country from the spinner, it will update the API link and fetch holidays for the selected country.

I’ve set the default API to “US” because the base url doesn’t return anything unless you add a country at the end. My code is running but when I choose other countries from the spinner, API link doesn’t update.
Any help is appreciated.

My MainActivity.kt


    private lateinit var binding : ActivityMainBinding
    private lateinit var holidayAdapter: HolidayAdapter
    private lateinit var holidayList : List<Holiday>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        this.binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(this.binding.root)

        // Initialize holidayAdapter
        holidayAdapter = HolidayAdapter(emptyList())
        binding.holidayRecyclerView.adapter = holidayAdapter
        binding.holidayRecyclerView.layoutManager = LinearLayoutManager(this)

        // Set up spinner
        binding.countrySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                val selectedCountry = parent?.getItemAtPosition(position).toString()
                connectToAPI(selectedCountry)
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {
                // Do nothing
            }
        }

    }


    private fun connectToAPI(countryCode: String) {
        val holidayAPI: API = RetrofitInstance.createAPI()

        lifecycleScope.launch {
            val response = holidayAPI.getAllHolidays(countryCode)

            val apiHolidayList: List<Holiday> = response

            holidayAdapter.setItems(apiHolidayList)

            Log.d("MainActivity", "Holiday List: $apiHolidayList")
        }
    }

My API.kt

interface API {
    @GET("{countryCode}")
    suspend fun getAllHolidays( @Path("countryCode") countryCode: String): List<Holiday>
}

My RetrofitInstance.kt:

object RetrofitInstance {
    // Base URL without the year and country code
    private const val BASE_URL = "https://date.nager.at/api/v3/PublicHolidays/2024/"

    private val moshi = Moshi.Builder()
        .add(KotlinJsonAdapterFactory())
        .build()

    // Custom Retrofit Builder to handle dynamic URLs
    private val retrofitBuilder = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(MoshiConverterFactory.create(moshi))

    // Function to create the Retrofit service with dynamic base URL
    fun createAPI(): API {
        val retrofit = retrofitBuilder.build()
        return retrofit.create(API::class.java)
    }
}

My HolidayAdapter.kt

class HolidayAdapter(private var holidayList: List<Holiday>) : RecyclerView.Adapter<HolidayAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.holiday_item, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val holiday = holidayList[position]
        holder.bind(holiday)

        // Add space between items except for the last item
        val marginBottom = if (position < holidayList.size - 1) {
            holder.itemView.resources.getDimensionPixelSize(R.dimen.item_bottom_margin)
        } else {
            0 // No margin for the last item
        }
        val layoutParams = holder.itemView.layoutParams as ViewGroup.MarginLayoutParams
        layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin, layoutParams.rightMargin, marginBottom)
        holder.itemView.layoutParams = layoutParams
    }


    override fun getItemCount(): Int {
        return holidayList.size
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val holidayNameTextView: TextView = itemView.findViewById(R.id.holidayNameTextView)
        private val holidayLocalNameTextView: TextView = itemView.findViewById(R.id.holidayLocalNameTextView)
        private val holidayDateTextView: TextView = itemView.findViewById(R.id.holidayDateTextView)

        fun bind(holiday: Holiday) {
            holidayNameTextView.text = holiday.name
            holidayLocalNameTextView.text = holiday.localName
            holidayDateTextView.text = holiday.date
        }
    }

    // Method to set a new list of items to the adapter
    fun setItems(holidays: List<Holiday>) {
        holidayList = holidayList + holidays
        notifyDataSetChanged()
    }
    ```

Leave a Comment