Search code examples
androidkotlinandroid-navigationandroid-safe-args

safeargs argument not found in NavDirections


I have implemented an argument to be passed between fragments in nav_graph, however when I attempt to set the argument in the originating fragment, the argument is not found by the NavDirections.

Note that Navigation works fine before trying to pass the argument.

If I do a Clean Project I lose the NavDirections. If I do a Rebuild I lose the argument.

Gradle:app

    //Navigation
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
    apply plugin: "androidx.navigation.safeargs.kotlin"

nav_graph.xml

    <fragment
        android:id="@+id/destination_home"
        android:name="com.android.joncb.flightlogbook.HomeFragment"
        android:label="@string/lblHome"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_home_to_fltHistory"
            app:destination="@id/destination_fltHistory" />
        <action
            android:id="@+id/action_home_to_stats"
            app:destination="@id/destination_statistics" />
        <action
            android:id="@+id/action_home_to_newFlight"
            app:destination="@id/destination_newFlight" />
        <action
            android:id="@+id/action_home_to_fltDetails"
            app:destination="@id/destination_fltDetails" />
        <argument
            android:name="fltData"
            app:argType="string" />
    </fragment>

and in my Home Fragment I get the error "Unresolved reference: fltData"

        card_nextFlight.setOnClickListener {
            val actionDetails = HomeFragmentDirections.actionHomeToFltDetails()
            actionDetails.fltData ( flightData.toString())

            Navigation.findNavController(it).navigate(actionDetails)
        }

flightData is a data class

data class FlightDTO(
    var airlineName: String, var faCode: String, var fltNo: String, var aircraft: String,
    var depAP: String, var arrAP: String, var schedDep: String, var schedArr: String,
    var date: String, var leg: Int = 0, var actDep: String = "", var actArr: String = "" ){

...

    override fun toString(): String {

        return "$airlineName $faCode $fltNo $aircraft $depAP $schedDep $arrAP $schedDep $date"
    }
}

I want to pass the class ideally by making the class Parcelable, but until I can pass a string, there is no point venturing down the parcel line.


Solution

  • Rather than pass a data class, I have created a JSON String and passed a string

            card_nextFlight.setOnClickListener {
                val dataString = flightData.toJSONString()
                val actionDetails = HomeFragmentDirections.actionHomeToFltDetails(dataString)
    
                Navigation.findNavController(it).navigate(actionDetails)
            }
    

    To get this to work I had to modify the actionHomeToFltDetails function to receive a string in HomeFragmentsDirections

        fun actionHomeToFltDetails(fltData: String): NavDirections = ActionHomeToFltDetails(fltData)
      }
    

    I could not get @Lucho approach to handle the arg in the destination fragment to work so reverted to bundle management, and converted the JSON string back to a data class

            const val ARG_PARAM1 = "fltData"
    .
    .
    .
            arguments?.let {
                argFltData = it.getString(ARG_PARAM1)
    
                Log.e("args","Passed Argument: $argFltData")
    
                fltData = gson.fromJson(argFltData, FlightDTO::class.java)
    
            }
    

    Thanks again for your input and I hope this helps someone else through the drama.