Home > Mobile >  Using Optional's ifPresentOrElse method but return promise instead of void
Using Optional's ifPresentOrElse method but return promise instead of void

Time:03-16

I'm trying to get my around a current issue I'm facing.

I have a function that returns an Optional type (an object with a few properties)

One of the properties is an url that might be present or not. I extract that url in order to make an HTTP request

injectedClass.method(tenant.clientKey()).flatMap(optionalProperty ->
                        optionalProperty.ifPresentOrElse(fi -> {
                                Blocking.get(() -> httpClientProvider.withHttpClient((HttpClient httpClient) ->
                                    httpClient.request(URI.create(optionalProperty.webTriggerUrl()), (RequestSpec spec) -> {
                                        LogstashMarker markers = append("webTriggerUrl", fi.webTriggerUrl()).and(append("method", "Post").and(append("behaviour", objectMapper.writeValueAsString(baseDTO))));
                                        logger.debug(markers, "Executed a Post request to something webTriggerUrl");
                                        spec.method(HttpMethod.POST);
                                        spec.getBody().type(HttpHeaderValues.APPLICATION_JSON).text(objectMapper.writeValueAsString(baseDTO), CharsetUtil.UTF_8);

                                        final MutableHeaders headers = spec.getHeaders();
                                        headers
                                                .set(HttpHeaderNames.USER_AGENT, userAgent);

                                        headers.set(CorrelationId.HEADER_NAME, correlationId.id());

                                    })
                            )).then(resp -> logger.info("ok"));
                        }, () -> logger.error("something"))

Blocking.get brings back a Promise and I get an error in my code basically saying that the expected return type of ifPresentOrElse should be void and not Promise

Is there a functional and better way to achieve this?

CodePudding user response:

Yes there are ways, but you also have to decide what to do if the Optional is empty. Currently you want to return a Promise if the optional is present, and return nothing ("void") if it is empty. This doesn't work, the types for both branches need to be the same.

You can just use optionalProperty.map() to map your original Optional to a Optional<Promise>, and then use ifPresentOrElse, to do something with either the Promise or with the empty Optional, e.g. logging as you seem to be doing in your case.

But you also have a higher-level flatMap which I'm unclear from which type it is. Does this flatmap a Promise? Then you must return a Promise also from the other branch of the optional, and you could use optionalProperty.map(...).orElse( <create empty Promise here> ).

Also check out orElseGet() instead of orElse(), if you want to create the empty branch lazily (via Supplier).

CodePudding user response:

ifPresentOrElse returns void. What you probably want is a combination of map and orElseGet:

optionalProperty.map(/* code to return a Promise */)
        .orElseGet(() -> /* code to return a Promise that is immediately resolved */);

Inside the supplier to orElseGet() you can put your logger.error statement.

  • Related