У меня есть две наблюдаемые разных типов, которые испускают два разных типа объектов. Но мне нужно обновить аналитику при успешном входе в систему с идентификатором пользователя и ролью. Идентификатор пользователя уже установлен в вызове функции входа в систему viewModel при успешном входе в систему.
viewModel.login(emailId)
.observeOn(AndroidSchedulers.mainThread())
.autoDisposable(scopeProvider)
.subscribe({ (role, images) ->
analyticsProvider.updateUser(mapOf(Constants.Role to role,
Constants.userId to *NEED TO ENTER USER ID FROM OTHER OBSERVABLE HERE*)))
My Session Observable, который испускает объект пользователя.
class SessionClass{
private val user = BehaviorSubject.create<User>()
override fun setUser(user: User) {
this.user.onNext(user)
}
override fun getUser(): Observable<User> = user.hide()
}
Я пытался вызвать SessionClass().getUser().blockingFirst().userId
в этом месте, но телефон зависает на экране входа в систему.
Можно ли как-то решить эту проблему?
Ваше решение не работает просто потому, что вы немедленно создаете экземпляр SessionClass
и никогда не вызываете setUser()
, поэтому getUser().blockingFirst()
заблокируется навсегда. Я предполагаю, что у вас есть экземпляр SessionClass
, который на самом деле будет вызывать setUser()
в какой-то момент.
Ключом к доступу к пользователю является комбинировать Observables. Подходящим выбором в этой ситуации является оператор zipWith
. Это позволит вам оперировать значениями из двух источников одновременно. Например, ваш код может выглядеть примерно так:
val session: SessionClass = TODO() // get an instance somewhere
viewModel.login(emailId)
.observeOn(AndroidSchedulers.mainThread())
.zipWith(session.getUser().firstOrError(), BiFunction { (role, images): Pair<Role, Images>, user: User -> Triple(role, images, user) })
.autoDisposable(scopeProvider)
.subscribe({ (role, images, user) ->
analyticsProvider.updateUser(mapOf(Constants.Role to role, Constants.userId to user.userId))
})))
А еще zipWith
не распознается после autoDisposable :(
@ASN a.zipWith(b, zipper)
похож на Observable.zip(a, b, zipper)
, за исключением того, что вы можете связать его, чтобы он выглядел лучше. После вызова autoDisposable
вы можете только subscribe
. Я обновил свой ответ, чтобы отразить это.
видимо viewModel.sessionManager().blockingGet().getUser()
это Observable<User>
. Но zipWith
ожидает Single вместо Observable
Вы можете использовать один из операторов first
, чтобы преобразовать его в Single
.
Но в этом случае что мне нужно передать как значение по умолчанию оператору first
.
Спасибо Панда. Попробую. Но у меня есть сомнения. Я использовал немного другой подход. Я использовал оператор zip и создал функцию Bi, которая возвращает экземпляр созданного мной пользовательского объекта, содержащего все поля. Есть ли причина, по которой zipWith выбран, а не zip?