ace
ace

Reputation: 12024

How to include multiple statements in the body of flatMap or flatMapMany for Mono or FLux in Spring Reactor?

I have below code:

        Mono<Property> property = propertyService.findById(id);

        String title;

        Flux<Photo> photos = property.flatMapMany(prop -> 
        {
            title = prop.title + '-' + prop.type;

          return photoService.findByPropertyId(prop.getId());
        }
        );
        model.addAttribute("prop", property);
        model.addAttribute("title", title);
        model.addAttribute("photos", photos);
        // ajx is query param coming from request
        if(ajx != null && !ajx.isEmpty() && ajx.equals("1"))
            return Mono.just("fragments/propertyfrag");
        else
        return Mono.just("property");

The code shows what I want to achieve but it does not even compile. It gives error saying title and type on prop are not visible.

Note that the last statement is reference to thymeleaf template named property. Withn thyeleaf template I have access to variable prop as if it was not reactive but plain prop object that enables me to directly access parameters on prop object. Does that mean within thymeleaf template property.block() has been performed?

In actual code there is some business logic that I need to do after getting title variable in above code and therefore I cannot avail the use of prop passed as model attribute to thymleaf template to directly get title within thymeleaf.

How to solve this problem?

Upvotes: 0

Views: 2003

Answers (1)

Simon Basl&#233;
Simon Basl&#233;

Reputation: 28301

Keep in mind your Flux<Photo> is an asynchronous process, so it cannot update the title variable outside of it in this imperative style. Note that your Flux<Photo> is also never subscribed to or composed upon, so it will effectively never be invoked...

To answer your other question, yes in Spring Framework 5 having a Mono in the Map passed to Thymeleaf will resolve that Mono lazily and inject the resulting value in the Thymeleaf model.

Pending more information on the use of photos flux, for the title generation you probably need to compose more:

propertyService.findById(id)
    .doOnNext(prop -> model.addAttribute("prop", prop)) //reactively add the prop to the model
    .flatMapMany(prop -> {
        String title = prop.title + '-' + prop.type;
        if(validate(title)) //do some validation
            return photoService.findByPropertyId(prop.getId());
        else
            return Mono.error(new IllegalArgumentException("validation failed"));
    }) //not sure what you do with the `Photo`s there :/
    //for now let's ignore the flux photos and at the end simply emit a String to change the view:
    .thenReturn("property"); //then(Mono.just("property")) in older versions of reactor 3.1.x

Upvotes: 1

Related Questions