1
votes

I'm new to WebFlux/Reactor and having trouble wrapping my head around how to write this piece of code. Basically, I have a Flux which has a nested List foo and a Mono<Set> bar and I'd like to only return items in foo that are contained in bar.

// these two lines are representations of what the data looks like
Flux<CategoryModel> foo = { Permissions = [ "UserRole1"] } // List<String>
Mono<Set<String>> bar = [ "UserRole1", "UserRole2" ]; 

var filteredFoo = foo.filter(m -> m.getPermissions().stream().anyMatch(perm -> bar.block().contains(foo)));

The problem with the above block of code is the .block() on the contains() and I don't want to block. Not sure how to change this to have non blocking but still check if bar contains the perm item.

2

2 Answers

2
votes

To answer the question directly - don't use filter(), use filterWhen(), which filters based on a publisher rather than a set value:

foo.filterWhen(m -> bar.map(set -> m.getPermissions().stream().anyMatch(perm -> set.contains(foo))));

Note that your code as-written is a bit odd however and I've just translated it directly - but it doesn't make much sense at the moment for a couple of reasons:

  • You're streaming over the permissions but not actually using the permission in your anyMatch() lambda at present - so currently your code could be simplified to:

    foo.filterWhen(m -> bar.map(set -> set.contains(foo)));
    
  • Even given the above, you're checking if your set contains foo, which is the flux itself, so there's no reasonable situation in which that would ever be true.

1
votes

You need to know the final content of your mono so that you can filter your flux, so just wait for it:

var filteredFoo = bar.flatMapMany(b -> foo.filter(f -> f.getPermissions().stream().anyMatch(b::contains)));