Reputation: 1079
I need to call a sequences of function to get all the information I need for a notification. First subscribe which opens up the session, then queryNotification
to listen on all the incoming notifications, and once a notification is received, need to call getNotificationAttrs
with the notificationId
returned in queryNotification
, then call getAppAttributes
with appIdentifier
returned in getNotificationAttrs
and I need the combined result of queryNotification
, getNotificationAttrs
and getAppAttributes
. How the functions look like are below:
func subscribeNotification() -> Single<Info>
func queryNotification() -> Observable<Notification>
func getNotificationAttrs(uid: UInt32, attributes: [Attribute]) -> Single<NotificationAttributes>
func getAppAttributes(appIdentifier: String, attributes: [AppAttribute]) -> Single<NotificationAppAttributes>
The tricky part is that queryNotification
returns Observable and both getNotificationAttrs
and getAppAttributes
return Single. What I have in mind of chaining them together is like:
subscribeNotification()
.subscribe(onSuccess: { info in
queryNotification()
.flatMap({ notification in
return getNotificationAttributes(uid: notification.uid, attributes: [.appIdentifier, .content])
})
.flatMap({ notifAttrs
return getAppAttributes(appIdentifier: notifAttrs.appIdentifier, attributes: [.displayName])
})
.subscribe {
// have all the result from last two calls
}
})
Is this doable? Any direction is appreciated! Thanks!
Upvotes: 1
Views: 3796
Reputation: 33967
The most obvious and IMHO correct solution is to promote your Single
into an Observable
. Also, I'm not a fan of the first subscribe
where it is. You end up with an indentation pyramid.
I'm following your comments about needing the values from all of queryNotification()
, getNotificationAttrs(did:attributes:)
and getAppAttributes(appIdentifier:attributes:)
...
let query = subscribeNotification()
.asObservable()
.flatMap { _ in queryNotification() }
.share(replay: 1)
let attributes = query
.flatMap { getNotificationAttrs(uid: $0.uid, attributes: [.appIdentifier, .content]) }
.share(replay: 1)
let appAttributes = attributes
.flatMap { getAppAttributes(appIdentifier: $0.appIdentifier, attributes: [.displayName]) }
Observable.zip(query, attributes, appAttributes)
.subscribe(onNext: { (query, attributes, appAttributes) in
})
The above will follow the steps you outlined and the subscribe will get called every time a new notification is emitted.
Also notice how the above reads quite a bit like synchronous code would (just with some extra wrapping.)
Upvotes: 4