My User object has a List<Post>
, each Post has a List<Tag>
.
Now I would like to add a Tag item to the List<Tag>
.
User:
data class User(
val id: String,
val name: String,
val posts: List<Post> = listOf()
)
Post:
data class Post(
val id: Int,
val name: String
val tags: List<Tags> = listOf()
)
Now I would like to update my MutableStateFlow containing the User object:
private val _userStateFlow: MutableStateFlow<User?> = MutableStateFlow(User())
val userStateFlow: StateFlow<User?> = _userStateFlow
To find the correct Post (containing the List<Tag>
I want to update) I have the id of it (passedPostId)
val postsList = userStateFlow.value?.posts!!.toMutableList()
val tagsList = postsList.find { it.id == passedPostId }?.tags?.toMutableList()
tagsList.add(Tag("test"))
Now I got an updated tagsList but I need an updated postsList to pass it to my MutableStateFlow. I am not sure how to do it. This is how I update my MutableStateFlow:
_userStateFlow.update { it?.copy(posts = newPosts)
If I have the index of the post I want to update everything works fine, but In my Case I only can call .find because all i have is the id of the post.
val posts = userStateFlow.value?.posts!!.toMutableList()
posts[index] = posts[index].copy(tags = posts[index].tags.plus(Tag("test")
userStateFlow.value = userStateFlow.value?.copy(posts = posts)
CodePudding user response:
You can create a function to add a tag to your immutable Post
object - may as well stick it inside the class:
data class Post(
val id: Int,
val name: String
val tags: List<Tag> = listOf()
) {
// copy this object, replacing the tag list with a copy that has the new one appended
fun addTag(newTag: Tag) = copy(tags = tags newTag)
}
Then you can do:
// alternative to putting it in the User class - whatever feels better
fun User.addTag(postId: Int, tag: Tag) =
// copy this User, including copying its list of Posts
// but any with a matching ID get the tag added
copy(posts = posts.map { post ->
if (post.id == postId) post.addTag(tag) else post
})
and update with
userStateFlow.value = userStateFlow.value!!.addTag(passedPostId, Tag("test"))
Try it here if you like
CodePudding user response:
I fixed it by simply getting the index of the Post so I could use the code that worked before:
val postPosition = postsList.indexOfFirst {
it.id == passedPostId
}
postsList[postPosition] = postsList[postPosition].copy(tags = tagsList)
_userStateFlow.update { it?.copy(posts = postsList)
I feel pretty stupid to not have thought of that in the first place.