Towards Dev

A publication for sharing projects, ideas, codes, and new theories.

Follow publication

Compose Navigation: Passing Objects

it is very easy to pass primitive and simple Args in navigation , but what if your compose function accept an argument of specific type for example your User Model?

the answer is by sending your object as JSON String then convert this JSON back to your TYPE in NavHost function :)

you can do conversion by using a library called Moshi

Moshi is a modern JSON library for Android, Java and Kotlin. It makes it easy to parse JSON into Java and Kotlin classes

the key functions you deal with: toJson and fromJson

toJson : to convert object to JSON String

fromJson: to convert JSON to object.

add library to your app module build.gradle:

implementation("com.squareup.moshi:moshi:1.14.0")  

implementation("com.squareup.moshi:moshi-kotlin:1.14.0") //for KotlinAdaperFactory

make an object of type Moshi:

val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory()) //form moshi-kotlin

.build()

create an Adapter from your class :

val jsonAdapter = moshi.adapter(User::class.java).lenient()   // am using user class 

now convert object to JSON :

val userJson = jsonAdapter.toJson(user)

and pass it instead of String args :

user/details/{user}
// we want to pass it instead of {user}

"user/details/{${userJson}}"

// of course you will use this when you do
// naVController.navigate("user/details/{${userJson}}")

inside NavHost:

NavHost{

composable(
"user/details/{user}"



) {backStackEntry ->



val userJsonString = backStackEntry.arguments?.getString("user")
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory()) //form moshi-kotlin
.build()
val jsonAdapter = moshi.adapter(User::class.java).lenient()
val userObject = jsonAdapter.fromJson(userJsonString)

UserDetailScreen(userObject)
}

and lastly your composable :

@Composable 
fun UserDetailScreen(userObject)

){...}

just to recap you have to do this in NavHost:

composable(
route = Destination.ServiceDetails.routeName+"/{service}" ,




){

val serviceJsonString = it.arguments?.getString("service")

val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory()) //form moahi-kotlin
.build()
val jsonAdapter = moshi.adapter(ServiceModel::class.java).lenient()
val serviceObject = serviceJsonString?.let { it1 -> jsonAdapter.fromJson(it1) }

ShowService(serviceObject!!)
}

and from the point when you need to navigate:

val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory()) //form moahi-kotlin
.build()
.build()
val jsonAdapter = moshi.adapter(ServiceModel::class.java).lenient()
val serviceToJson =jsonAdapter.toJson(mainViewModel.viewState.value.selectedServiceModel)
navController.navigate(Destination.ServiceDetails.routeName+"/${serviceToJson}")

thanks for reading:)

References :

https://github.com/square/moshi

Sign up to discover human stories that deepen your understanding of the world.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in Towards Dev

A publication for sharing projects, ideas, codes, and new theories.

Written by Kururu

Android | Flutter | Data Analytics

No responses yet

Write a response