In the below code logic switchIfEmpty is not getting executed. As per below code logic I am expecting lowerCase names when filter(__ -> names.size() > 5) evaluates to false and upperCase names when filter(__ -> names.size() > 3) evaluates to true. It is working as expected if filter evaluates true but it is not working when filter evaluates to false. Why is that?
List<String> names = Arrays.asList("google", "abc", "fb", "stackoverflow");
Flux.fromIterable(names)
.filter(name -> name.length() > 5)
.collectList()
.flatMap(commonAppliedFilters -> Mono.just(commonAppliedFilters)
.filter(__ -> names.size() > 5)
.flatMapIterable(list -> list)
.map(String::toUpperCase)
.collectList()
.switchIfEmpty(Mono.defer(() -> Mono.just(commonAppliedFilters))))
.subscribe(System.out::println);
In the below code logic switchIfEmpty is not getting executed. As per below code logic I am expecting lowerCase names when filter(__ -> names.size() > 5) evaluates to false and upperCase names when filter(__ -> names.size() > 3) evaluates to true. It is working as expected if filter evaluates true but it is not working when filter evaluates to false. Why is that?
List<String> names = Arrays.asList("google", "abc", "fb", "stackoverflow");
Flux.fromIterable(names)
.filter(name -> name.length() > 5)
.collectList()
.flatMap(commonAppliedFilters -> Mono.just(commonAppliedFilters)
.filter(__ -> names.size() > 5)
.flatMapIterable(list -> list)
.map(String::toUpperCase)
.collectList()
.switchIfEmpty(Mono.defer(() -> Mono.just(commonAppliedFilters))))
.subscribe(System.out::println);
Share
Improve this question
edited Mar 24 at 18:58
Doug Breaux
5,1051 gold badge27 silver badges68 bronze badges
asked Mar 19 at 11:10
SuhailSuhail
11 bronze badge
1 Answer
Reset to default 0What happened is that the collectList returned a Mono with an empty list
, but not a Mono.empty
, so we have:
...
.collectList()
.filter(list -> !list.isEmpty())
or
...
.collectList()
.flatMap(list -> !list.isEmpty() ? Mono.just(list) : Mono.empty())
With this we successfully force a Mono.empty()
that will trigger your switchIfEmpty()
.
I show you an example testing with StepVerifier
.
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
<version>3.7.0</version>
</dependency>
You can decomment the flatMap to see how it works as well.
class ReactiveTest {
@Test
@DisplayName("expecting lowerCase names when filter(__ -> names.size() > 5)")
void expectingLowerCase() {
List<String> names = Arrays.asList("google", "abc", "fb", "stackoverflow");
StepVerifier.create(Flux.fromIterable(names)
.filter(name -> name.length() > 5)
.collectList()
.flatMap(commonAppliedFilters ->
Mono.just(commonAppliedFilters)
.filter(__ -> names.size() > 5)
.flatMapIterable(list -> list)
.map(String::toUpperCase)
.collectList()
//.flatMap(list -> !list.isEmpty() ? Mono.just(list) : Mono.empty())
.filter(list -> !list.isEmpty())
// If the list is empty, a Mono.empty() is returned which will force switchIfEmpty
.switchIfEmpty(Mono.defer(() -> Mono.just(commonAppliedFilters)))
))
.expectNext(List.of("google", "stackoverflow"))
.verifyComplete();
}
@Test
@DisplayName("expecting upperCase names when filter(__ -> names.size() > 3) ")
void expectingUpperCase() {
List<String> names = Arrays.asList("google", "abc", "fb", "stackoverflow");
StepVerifier.create(Flux.fromIterable(names)
.filter(name -> name.length() > 5)
.collectList()
.flatMap(commonAppliedFilters ->
Mono.just(commonAppliedFilters)
.filter(__ -> names.size() > 3)
.flatMapIterable(list -> list)
.map(String::toUpperCase)
.collectList()
// .flatMap(list -> !list.isEmpty() ? Mono.just(list) : Mono.empty())
.filter(list -> !list.isEmpty())
.switchIfEmpty(Mono.defer(() -> Mono.just(commonAppliedFilters)))
))
.expectNext(List.of("GOOGLE", "STACKOVERFLOW"))
.verifyComplete();
}
}