Search code examples
androidkotlinandroid-fragmentsandroid-architecture-navigation

Error moving to a new fragment with NavigationComponents


So, this is weird, I have 2 ways of going to Fragment B from Fragment A

First one is from a fab button click

private fun navigateToCreateTopics(){
        fab_goto_topics.setOnClickListener {
            findNavController().navigate(R.id.action_destination_my_topics_to_destination_create_topics)
        }
    }

And I have items that has an edit button that also goes to the same fragment but with a bundle to edit those values

 val bundle = Bundle()
                        bundle.putBoolean("shouldEdit",true)
                        bundle.putParcelable("topic",topicAdapter.topicList[position])
                        findNavController().navigate(R.id.action_destination_my_topics_to_destination_create_topic,bundle)

Now, if I press the fab button to navigate without extras to the createTopics fragment it will throw this exception

Fragment CreateTopicsFragment{216b801} (69e0b0ac-1352-4daf-aa36-717c2f320cc9) id=0x7f0800ac} does not have any arguments.

And I dont know why because I'm not passing any arguments with the fab, and the line

requireArguments().let {
            ...
        }

should not execute since it checks for nulls and there is no arguments passing

Why this happends ?


Solution

  • As per the requireArguments() documentation:

    Throws IllegalStateException if no arguments were supplied to the Fragment.

    You'd want to use arguments if you want a nullable Bundle:

    arguments?.let {
            ...
    }
    

    Of course, you can also follow the define destination arguments documentation and add a defaultValue to your <argument> on your destination:

    <argument
         android:name="shouldEdit"
         app:argType="boolean"
         android:defaultValue="false" />
    

    Which will ensure you always have an argument Bundle set and either false, the default value, or your own value.

    This approach works particularly well when using Safe Args, which would replace your entire let with type safe calls:

    val args: CreateTopicsFragmentArgs by navArgs
    val shouldEdit = args.shouldEdit