Reputation: 639
In my application I have an array of notifications. Notification can be read and unread.
When user clicks on the unread notification I need to change the model and reload data in my table view.
In my ViewModel I have output stream:
let notifications: Driver<[Notification]>
And aslo I have an input stream with notification click:
let touchSingleNotificationIntent = PublishSubject<Notification>()
When I do something like this I get the error that it's let constant and I cannot mutate it.
touchSingleNotificationIntent
.filter { !$0.isRead }
.do(onNext: { notification in
notification.isRead = true // I need to change state of the model immediately after user iteration
})
.map { $0.notificationID }
.flatMap(markNotificationAsRead) // http request which doesn't reply with current notification model status
.subscribe()
.disposed(by: bag)
Do you have any ideas how to make it mutable? Thanks.
Upvotes: 0
Views: 5683
Reputation: 9382
Streams aren't Mutable at all (this is the same for Observable
, Driver
, and any other traits). They are "Read only", you read values off the stream over time.
In general, the conception Observables has a "value" is a bit wrong since Observables represent a value over time, and not just a single value.
What you would want to do is "take into account" your PublishSubject
when building out your driver.
Something like this would work:
notifications = Observable
.combineLatest(touchedNotification, readNotification, otherEvent) { ($0, $1, $2) }
.map { ... map the three values into whatever makes sense for you }
.asDriver(onErrorJustReturn: ... fallback value ... }
Again, the most important fact to remember - You do not actually mutate streams, you only combine them, transform them, etc, to create a new stream that suits your needs.
Hope this helps you!
Upvotes: 1
Reputation: 4077
Parameters of onNext are let by default. You can define a new one with var, i.e. 'var newNotification = notification' and then return it after modifying.
Upvotes: 0