I’m a junior Android developer and trying to build a Facebook-like social media app. My issue is that when I bookmark a post in Screen B and the action succeeds, (1) I want to launch an API request in Screen A while in Screen B and (2) update the bookmarked icon ONLY for that particular post.
For the second part of the issue, I tried these two solutions.
I relaunched a manual API request on navigating back to Screen A. This updates the whole list when there’s only one small change, hence very inefficient.
I built another URL route to fetch that updated post only and launched it on navigating back to Screen A. But to insert the newly updated post at the old index, the list has to be mutable and I ain’t sure this is a good practice.
Please help me on how to solve this issue or similar issues. I’m not sure if this should be done by passing NavArg to update locally and then some or by using web sockets. Thanks in advance.
data class ScreenAState(
val posts: List<Post> = emptyList(),
val isLoading: Boolean = false)
data class ScreenBState(
val post: PostDetail? = null,
val isBookmarked: Boolean? = null)
data class Post(
val title: String,
val isBookMarked: Boolean,
val imageUrl: String)
data class PostDetail(
val title: String,
val content: String,
val isBookMarked: Boolean,
val imageUrl: String)
2
Answers
The problem is how to handle data consistency, which is not directly related to jetpack compose. I suggest you solve this problem at the model level. Return flow instead of static data in the repository, and use
collectAsState
in the jetpack compose to monitor data changes.It’s hard to give an example, because it depends on the type of Model layer. If it’s a database, androidx’s room library supports returning flow; if it’s a network, take a look at this.
https://gist.github.com/FishHawk/6e4706646401bea20242bdfad5d86a9e
Triggering a refresh is not a good option. It is better to maintain an ActionChannel in the repository for each list that is monitored. use the ActionChannel to modify the list locally to notify compose of the update.
For example, you can make a PagedList if the data layer is network. With onStart and onClose, channels can be added or removed from the repository, thus giving the repository the ability to update all the observed lists.
And in repository:
I suggest you continue with using your logic that will update your list on return from screen B to screen A, but instead of using simple list, you could use:
https://developer.android.com/reference/kotlin/androidx/compose/runtime/snapshots/SnapshotStateList
This list is designed for what you need I think. Update just that one element.
In mean time, you can change that item from list to some loading dummy item, if you want to have loading like view while you wait for API call to finish.