Android LiveData - switchMap не запускается при втором обновлении

У меня есть LiveData объект, который зависит от другого LiveData, Насколько я понимаю, Transformations.switchMap должен позволять связывать их Но switchMap Обработчик срабатывает только один раз и не реагирует на дальнейшие обновления. Если вместо этого я использую observe на первом объекте и, когда он будет готов, получить второй, он работает нормально, но в этом случае я должен сделать это в Activity скорее, чем ViewModel, Можно ли связать LiveData объекты, как Transformations.switchMap, но получать все обновления, а не только первое?

Вот попытка использовать switchMap:

LiveData<Resource<User>> userLiveData = usersRepository.get();
return Transformations.switchMap(userLiveData, resource -> {
    if (resource.status == Status.SUCCESS && resource.data != null) {
        return apiService.cartItems("Bearer " + resource.data.token);
    } else {
        return AbsentLiveData.create();
    }
});

Вот подход с observe в деятельности (работает, но требует соблюдения логики в деятельности):

viewModel.user().observe(this, x -> {
    if (x != null && x.data != null) {
        viewModel.items(x.data.token).observe(this, result -> {
            // use result
        });
    }
});

1 ответ

Решение

В качестве обходного пути я использовал MediatorLiveData, Я добавляю результат первого вызова в качестве источника и, когда он готов, заменяю его на последний вызов:

MediatorLiveData<MyResponse> result = new MediatorLiveData<>();
LiveData<Resource<User>> source = this.get();
result.addSource(source, resource -> {
    if (resource.status == Status.SUCCESS && resource.data != null) {
        result.removeSource(source);
        result.addSource(apiService.cartItems("Bearer " + resource.data.token), result::postValue);
    }
});
return result;

Я пытался сделать что-то похожее на тебя. У меня есть LiveDatasomething, и когда это изменится, я хочу запросить somethingElseиз БД на основе свойства. Поскольку свойство может иметь значение null, если я запрошу его с его помощью, я получу исключение. Следовательно, если свойство равно null, я возвращаю пустой MutableLiveData.

Я заметил, что когда я вернул этот пустой MutableLiveData, наблюдатели, которые подписались на somethingElseне получали никаких обновлений. Я видел, что в вашем ответе вы в конечном итоге использовали MediatorLiveData. Затем я прошел через свой код с помощью отладчика и заметил, что switchMap также использует MediatorLiveData.

Немного поэкспериментировав, я понял, что при создании пустого MutableLiveData его начальное значение равно нулю и не запускает никаких обновлений. Если я явно установлю значение, оно уведомит наблюдателей.

somethingElse = Transformations.switchMap(something, somethingObject -> {
                if (something.someProperty() != null) {
                    return repository.getSomethingElseByProperty(something.someProperty());
                }else{
                    MutableLiveData<SomethingElse> empty = new MutableLiveData<>();
                    empty.setValue(null);//need to set a value, to force update of observers
                    return empty;
                }

Код здесь сработал для меня. В вопросе вы используете AbsentLiveData, и я не знаю, как это реализовано, поэтому я не уверен, что он будет работать именно в этом случае.