How can I use Mono<Boolean> as condition to call second method - spring-webflux

I'm trying to make a call to one service after checking a condition from another service in an iterative way, like so:
if (productService.isProductNotExcluded(product)){
List<Properties> properties = propertiesService.getProductDetailProperties(product)
...
}
But since isProductExcluded is returning Mono<Boolean> I'm using this approach, which seems really odd:
Flux<Properties> properties = productService.isProductNotExcluded(productId)
.filter(notExcluded -> notExcluded)
.map(ok-> propertiesService.getProductDetailProperties(product))
...
Which is the correct way to deal with this kind of situation?

For a predicate which returns a Mono<Boolean>, you can also use filterWhen which takes a publisher as a predicate. Something like this:
Flux<Properties> properties = Mono.just(productId)
.filterWhen(prodId -> productService.isProductNotExcluded(prodId))
.map(validProductId -> propertiesService.getProductDetailProperties(validProductId));

What you are doing is not odd. I personally wouldn't return a boolean in a reactive function Mono<Boolean> if I can avoid it, but it's not wrong and sometimes you don't have a choice.
I personally would have an if/else statement in the map, for clarity. I would also change the name of the function, and rewrite the isNot part.
Flux<Properties> properties = productService.isExcluded(productId)
.flatMap(isExcluded -> {
if(!isExcluded)
return propertiesService.getProductDetailProperties(product);
else
return mono.empty();
});
This is matter of opinion and coding taste, but I find this to be a lot more readable, because you can read the code and understand it straight away. But this is a personal taste.

all() operator can be used.
According to the doc. all() Emits a single boolean true if all values of this sequence match
Mono all(Predicate<? super T> predicate) {}

Related

Is there a use for the "with" function that I can't achieve by "apply", "run", "also" or "let" in Kotlin?

When would we ever need with in Kotlin if we can already use apply, run, also and let?
Can anyone give me a clear example?
In most situations, a with call can be transformed to a run like this:
with(foo) {
// some code ...
}
// is the same as:
foo.run {
// the same code ...
}
run and with will both return the lambda result, and will use foo as the lambda receiver.
However, I can think of one case where this wouldn't work - when foo declares its own run method that takes a lambda, e.g.
// having something like this isn't too uncommon, right?
fun run(x: () -> Unit) {}
The lambda type doesn't have to be exactly the same as the scope function run. Any function type should work. Then overload resolution wouldn't resolve to the built-in run.
You can force the resolution by doing some casts, but using with in this case is much better. Don't you agree?
I don’t think there’s any better example than with(context). Maybe it’s not clear if English isn’t one of your primary languages, but it semantically is translated into English much clearer than context.run when the object is being used to produce a result but isn’t the primary actor, so it makes code a little easier to read.
This of course raises the question of why run exists. Well, it semantically makes more sense in English when the object is the thing doing the action. In English, the context of an action is what you’re doing something with. But if the object is what is directly producing the result, then it is running the action.
Also, you can’t do ?.with.

Doing this on kotlin is a bad practice?

The second way is a little smaller but i dont know if this is okay, can i use also just for be able to use expression body and put the first line of the cod on the side of method name?
override fun findOrdensColeta() {
view.setProgressBarVisibility(View.VISIBLE)
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
override fun findOrdensColeta() = view.setProgressBarVisibility(View.VISIBLE).also {
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
Yes, I think the second version is bad style. I see no good reasons to use also() like that, and several reasons not to:
also() is intended for use within expressions, where you don't have the option of adding a separate statement. (The classic case is logging a value before doing something with it.) That doesn't apply here, where two simple statements work just as well. So there's no benefit other than conciseness; using also() here is unnecessary complexity.
The second version has an expression body, which looks like it returns a useful value — but it actually returns the result of calling setProgressBarVisibility(), which is presumably Unit just like the first version. So the expression body is highly misleading.
Also, the only reason that the second version is shorter is that the first statement has been squeezed onto the same line. I don't think that's justified here* — it joins two things (the function signature and the call to setProgressBarVisibility()) that aren't directly related, and it makes the line too long for most people to read easily. (I'm surprised you find the second version easier to read. I tend to prefer conciseness, but even I find the first version a good deal easier to read — probably because it falls into a very familiar pattern that doesn't need any extra thought.)
If you cared only about reducing the number of lines, then the first version could be written like this (not recommended!):
override fun findOrdensColeta() { view.setProgressBarVisibility(View.VISIBLE)
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
(You could join even more lines, perhaps squeezing it all onto a single line if you wanted to make it completely unreadable!)
Conversely, if there were other good reasons for using the second version, it would be better if wrapped like this:
override fun findOrdensColeta()
= view.setProgressBarVisibility(View.VISIBLE).also {
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
So as you can see, the difference in length is mainly due to the (unjustified and confusing) line-joining, not the use of also().
So using also() here has no real benefit, as well as some significant drawbacks.
* I'm not saying you should never put the function body on the same line as its signature. That can work well if the body is an expression that's short enough to fit neatly all one line. For example:
override fun toString() = "MyClass(val1 = $val1)"
However, if that makes the line very long, or wraps onto further lines, or is a function body, then it's almost always more readable to start the body on the next line in the traditional fashion.
I believe the second one is a bad approach.
also is designed to provide the ability to modify or use the receiver and return it afterwards.
In your case, also is not containing any usages of its receiver (which is the result of view.setProgressBarVisibility(View.VISIBLE) ). Therefore it is not needed here
The second version is a bit confused to me - if you take the first one as the standard way to do things, a simple code block with two statements in it, what benefit does the second one really give you? You're basically using expression syntax to make it a one-liner - but it's not a one-liner, so you have to add a scope function just to give yourself back the curly braces so you can add another line of code!
So this:
override fun findOrdensColeta() {
view.setProgressBarVisibility(View.VISIBLE)
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
Does exactly the same thing as this:
override fun findOrdensColeta() = view.setProgressBarVisibility(View.VISIBLE).also {
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
But with the latter
it appears to return a result from setProgressBarInvisibility because it's a single-expression function (the original clearly returns nothing)
the use of also which passes that result value through reinforces the idea that you're trying to return that result
the also block implies you're using that value for something (otherwise why's it there?) and it takes a moment to see that you're not
when you realise none of the above are true, now you might be wondering if you're missing something, or if the original coder intended something specific but made a mistake
Because the basic function block is so simple and readable and a natural fit for what you're doing, doing something else can throw up some questions, or be confusing to read. Sure the way it's formatted you've saved a single line, but now it's harder to understand, y'know?
This is something to watch out for in Kotlin I think (and I'm guilty of this myself) - being able to chain stuff together sometimes encourages people to go for "one-liners" that are hard to follow, but hey at least you didn't (explicitly) create a variable! That's not what you're doing here (you're creating an unnecessary variable actually!) but it feels like a similar thing - trying to make a single expression instead of doing things the old-school way.
Coding is about trying to strike that balance between simplicity and readability, and elegant efficiency, and a lot of it's about learning what tools and tricks are available, and knowing when to use them (and how best to do it) and when to avoid them. At the end of the day it's a style choice and this is just my opinion (although all the other commenters so far are saying similar things) but hopefully it's given you something to think about! I've been there too - including using expressions for functions that don't return a value at all - but I think that's all part of learning a language and the things it offers you

Using Kotlin's scope functions in not exhaustive with / when

I'm pretty new with Kotlin and I'm trying to figure out Kotlin's scope functions.
My code looks like this:
with(something) {
when {
equals("test") -> var1 = "test123"
startsWith("test2") -> var2 = "test456"
contains("test3") -> myNullableVar?.let { it.var3 = "test789" }
}
}
So before I entered the third check with the .let function my with function does not need to be exhaustive (I'm not returning something, I'm only doing assignments). In my third check I'm using .let as a null-check ... but only for an assignment of it.var3 (if it is not null). I don't need to return anything while I know that Kotlin's .let function returns the result of the body by standard.
Nevertheless now my with/when needs to be exhaustive otherwise it won't compile anymore.
This got me thinking and trying out different things. I found these ways to solve this issue:
I can add an else to my with/when so it becomes exhaustive but actually I don't need an else and I don't want to use it in this case.
I can add another .let, so it looks like this: myNullableVar?.let { it.var3 = "test789" }.let{} .... but this looks kinda hacky to me. Is it supposed to work like this?
Use If(xy==null){...}else{...} stuff but I thought I can solve this with Kotlin differently
Because I'm new with Kotlin I'm not really sure how to handle this case properly. I would probably just go with my second idea because "it works". Or should I don't use .let for null-checks? Add another empty .let{}? Or did I not get the null-safety concept at all? I feel a little bit lost here. Thanks for any help.
This seems to be an unfortunate combination of features…
A when can be non-exhaustive only when it doesn't return a value.  The problem is that the with() function does return a value.  And since the when is at the bottom, its value is what gets returned, so in this case it must be exhaustive.
So why doesn't it insist on an else branch even if you omit the "test3" branch?  That's because assignments don't yield a value.  (They evaluate to Unit, which is Kotlin's special type for functions that don't return a useful value.)  If every branch gives Unit, then Kotlin seems* to be happy to infer a default branch also giving Unit.
But the "test3" branch returns something else — the type of myNullableVar.  So what type does the when infer?  The nearest common supertype of that type and Unit, which is the top type Any?.  And now it needs an explicit else branch!
So what to do?
You've found a few options, none of which is ideal.  So here are a few more, ditto!
You could return an explicit Unit from that branch:
contains("test3") -> { myNullableVar?.let { it.var3 = "test789" }; Unit }
You could return an explicit Unit from the with():
contains("test3") -> myNullableVar?.let { it.var3 = "test789" }
}
Unit
}
You could give an explicit type for the with(). (It has two type parameters, so you'd need to give both, starting with the type of its parameter):
with<String, Unit>("abc") {
I haven't found a single obvious best answer, I'm afraid…
And to answer your last question: yes, ?.let{ is perfectly idiomatic and common for null checks.  In this particular case, replacing it with an if happens to solve the type problem:
contains("test3") -> { if (myNullableVar != null) myNullableVar.var3 = "test789" }
But as well as being long-winded, if myNullableVar is a property and not a local variable, then it opens up a race condition (what if another thread sets it to null in between the test and the assignment?) so the compiler would complain — which is exactly why people use let instead!
(* I can't find a reference for this behaviour.  Is there an official word on it?)

What is the difference between not-null checks in Kotlin?

There are some ways to fulfill a null-checking in Kotlin:
1.
if(myVar != null) {
foo(myVar)
}
2.
myVar?.let {
foo(it)
}
3.
myVar?.run {
foo(this)
}
What are the difference between these ways?
Are there any reasons (performance, best practice, code style etc.) why I should prefer on way over the other?
!! is to tell the compiler that I am sure the value of the variable is not null, and if it is null throw a null pointer exception (NPE) where as ?. is to tell the compiler that I am not sure if the value of the variable is null or not, if it is null do not throw any null pointer.
Another way of using a nullable property is safe call operator ?.
This calls the method if the property is not null or returns null if that property is null without throwing an NPE (null pointer exception).
nullableVariable?.someMethodCall()
All three code are behave same null check in operation-wise.
?. is used for chain operations.
bob?.department?.head?.name // if any of the properties in it is null it returns null
To perform a chain operation only for non-null values, you can use the safe call operator together with let
myVar?.let {
foo(it)
}
the above code is good for code style and performance
more details refer Null Safety
The ways 2 and 3 are more idiomatic for Kotlin. Both functions are quite similar. There is little difference with argument passing.
For example, we have a nullable variable:
var canBeNull: String? = null
When you working with T.run you work with extension function calling and you pass this in the closure.
canBeNull?.run {
println(length) // `this` could be omitted
}
When you call T.let you can use it like lambda argument it.
canBeNull?.let {
myString -> println(myString.length) // You could convert `it` to some other name
}
A good article about Kotlin standard functions.
All three are roughly equivalent.
The if case is more like most other languages, and so many developers may find it easier to read.
However, one difference is that the if case will read the value of myVar twice: once for the check, and again when passing it to foo(). That makes a difference, because if myVar is a property (i.e. something that could potentially be changed by another thread), then the compiler will warn that it could have been set to null after the check. If that's a problem (e.g. because foo() expects a non-null parameter), then you'll need to use one of the other cases.
For that reason, the let case has become fairly common practice in Kotlin. (The run case does just about the same thing, but for some reason isn't as popular for this sort of thing. I don't know why.)
Another way around it is to assign myVar to a temporary value, test that, and then use that. That's also more like other languages, but it's more verbose; many people prefer the conciseness of the let case — especially when myVar is actually a complicated expression.
The examples in your question don't show the true reason to decide.
First of all, since you're not using the return value of foo, you should use neither let nor run. Your choice is between also and apply.
Second, since you already have the result you want to null-check in a variable, the difference fades. This is a better motivating example:
complexCall(calculateArg1(), calculateArg2())?.also {
results.add(it)
}
as opposed to
val result = complexCall(calculateArg1(), calculateArg2())
if (result != null) {
results.add(result)
}
The second example declares an identifier, result, which is now available to the rest of the lexical scope, even though you're done with it in just one line.
The first example, on the other hand, keeps everything self-contained and when you go on reading the rest of the code, you are 100% confident that you don't have to keep in mind the meaning of result.
Kotlin have new features with NullPoint-Exception as Compare to Java.
Basically When we do Coding in Java , then we have to Check with !! in every Flied.
But in Kotlin, it is Easy way to Implement First
as Like,
Suppose, in Kotlin
var response:Json?=Null
response:Json?.let {
this part will handle automatic if response is Not Null....then this Block start Executing }?.run {
This is Nullable But, where we Can put Warring } So, I am Suggest you Guys to Start Work in Kotlin with this Features Provided by Kotlin.
(Flied)?.let { Not Null Value Comes Under }?.run{ Null Value Code }
This will Handle to NullPoint Exception or Protect You App for Crash
What you want to achieve
What you want to achieve is that the Kotlin compiler does a smart cast on the variable you are working with.
In all of your three examples, the compiler can do that.
Example:
if(myVar != null) {
foo(myVar) // smart cast: the compiler knows, that myVar can never be null here
}
The choice
Which one of the options to use, is really a matter of style. What you should not do is mix it up to often. Use one and stick to it.
You don't need to worry about performance since let and run are inlined (see inline function). This means that their code (body) is copied to the call site at compile time so there is no runtime overhead.

Boolean method naming readability

Simple question, from a readability standpoint, which method name do you prefer for a boolean method:
public boolean isUserExist(...)
or:
public boolean doesUserExist(...)
or:
public boolean userExists(...)
public boolean userExists(...)
Would be my prefered. As it makes your conditional checks far more like natural english:
if userExists ...
But I guess there is no hard and fast rule - just be consistent
I would say userExists, because 90% of the time my calling code will look like this:
if userExists(...) {
...
}
and it reads very literally in English.
if isUserExist and if doesUserExist seem redundant.
Beware of sacrificing clarity whilst chasing readability.
Although if (user.ExistsInDatabase(db)) reads nicer than if (user.CheckExistsInDatabase(db)), consider the case of a class with a builder pattern, (or any class which you can set state on):
user.WithName("Mike").ExistsInDatabase(db).ExistsInDatabase(db2).Build();
It's not clear if ExistsInDatabase is checking whether it does exist, or setting the fact that it does exist. You wouldn't write if (user.Age()) or if (user.Name()) without any comparison value, so why is if (user.Exists()) a good idea purely because that property/function is of boolean type and you can rename the function/property to read more like natural english? Is it so bad to follow the same pattern we use for other types other than booleans?
With other types, an if statement compares the return value of a function to a value in code, so the code looks something like:
if (user.GetAge() >= 18) ...
Which reads as "if user dot get age is greater than or equal to 18..." true - it's not "natural english", but I would argue that object.verb never resembled natural english and this is simply a basic facet of modern programming (for many mainstream languages). Programmers generally don't have a problem understanding the above statement, so is the following any worse?
if (user.CheckExists() == true)
Which is normally shortened to
if (user.CheckExists())
Followed by the fatal step
if (user.Exists())
Whilst it has been said that "code is read 10x more often than written", it is also very important that bugs are easy to spot. Suppose you had a function called Exists() which causes the object to exist, and returns true/false based on success. You could easily see the code if (user.Exists()) and not spot the bug - the bug would be very much more obvious if the code read if (user.SetExists()) for example.
Additionally, user.Exists() could easily contain complex or inefficient code, round tripping to a database to check something. user.CheckExists() makes it clear that the function does something.
See also all the responses here: Naming Conventions: What to name a method that returns a boolean?
As a final note - following "Tell Don't Ask", a lot of the functions that return true/false disappear anyway, and instead of asking an object for its state, you tell it to do something, which it can do in different ways based on its state.
The goal for readability should always be to write code the closest possible to natural language. So in this case, userExists seems the best choice. Using the prefix "is" may nonetheless be right in another situations, for example isProcessingComplete.
My simple rule to this question is this:
If the boolean method already HAS a verb, don't add one. Otherwise, consider it. Some examples:
$user->exists()
$user->loggedIn()
$user->isGuest() // "is" added
I would go with userExists() because 1) it makes sense in natural language, and 2) it follows the conventions of the APIs I have seen.
To see if it make sense in natural language, read it out loud. "If user exists" sounds more like a valid English phrase than "if is user exists" or "if does user exist". "If the user exists" would be better, but "the" is probably superfluous in a method name.
To see whether a file exists in Java SE 6, you would use File.exists(). This looks like it will be the same in version 7. C# uses the same convention, as do Python and Ruby. Hopefully, this is a diverse enough collection to call this a language-agnostic answer. Generally, I would side with naming methods in keeping with your language's API.
There are things to consider that I think were missed by several other answers here
It depends if this is a C++ class method or a C function. If this is a method then it will likely be called if (user.exists()) { ... } or if (user.isExisting()) { ... }
not if (user_exists(&user)) .
This is the reason behind coding standards that state bool methods should begin with a verb since they will read like a sentence when the object is in front of them.
Unfortunately lots of old C functions return 0 for success and non-zero for failure so it can be difficult to determine the style being used unless you follow the all bool functions begin with verbs or always compare to true like so if (true == user_exists(&user))
Why not rename the property then?
if (user.isPresent()) {
Purely subjective.
I prefer userExists(...) because then statements like this read better:
if ( userExists( ... ) )
or
while ( userExists( ... ) )
In this particular case, the first example is such horrible English that it makes me wince.
I'd probably go for number three because of how it sounds when reading it in if statements. "If user exists" sounds better than "If does user exists".
This is assuming it's going to be to used in if statement tests of course...
I like any of these:
userExists(...)
isUserNameTaken(...)
User.exists(...)
User.lookup(...) != null
Method names serves for readability, only the ones fit into your whole code would be the best which most of the case it begins with conditions thus subjectPredicate follows natural sentence structure.
Since I follow the convention to put verb before function name, I would do the same here too:
//method name
public boolean doesExists(...)
//this way you can also keep a variable to store the result
bool userExists = user.doesExists()
//and use it like a english phrase
if (userExists) {...}
//or you can use the method name directly also and it will make sense here too
if (user.doesExists()) {...}