Hi, I’m curious if this can be rewritten with `whe...
# announcements
b
Hi, I’m curious if this can be rewritten with
when
block (
hasMaxRole
is extension method on my
User
data class):
Copy code
if (loggedInUser.hasMaxRole(<http://Role.NO|Role.NO>_ROLE)) {
    ResponseEntity(HttpStatus.FORBIDDEN)
} else if (loggedInUser.hasMaxRole(Role.USER_ROLE)) {
    if (loggedInUser.id == id) {
        ResponseEntity.ok(loggedInUser)
    } else {
        ResponseEntity(HttpStatus.FORBIDDEN)
    }
} else {
    userApiService.findById(id)
}
I would like something like this:
Copy code
when(loggedInUser) {
    hasMaxRole(<http://Role.NO|Role.NO>_ROLE) -> ResponseEntity(HttpStatus.FORBIDDEN)
    hasMaxRole(Role.USER_ROLE) && (loggedInUser.id == id) -> ResponseEntity.ok(loggedInUser as Any)
    hasMaxRole(Role.USER_ROLE) ->  ResponseEntity(HttpStatus.FORBIDDEN)
    else -> userApiService.findById(id)
}
(even with this code, I am repeating
loggedInUser
in second match since I need to call it twice in && operation)
j
The easiest way is to rewrite your extension function to return the actual Role, and then branch based on that. Remember you can use the
in
operator to check for whether a value belongs to a collection. Assuming Role is an enum or a sealed class, the compiler will check whether you've considered all branches.
Copy code
when(loggedInUser.role) {
  NO_ROLE -> ResponseEntity(HttpStatus.FORBIDDEN)
  USER_ROLE -> if(id == loggedInUser.id) ResponseEntity.ok(loggedInUser) else ResponseEntity(HttpStatus.FORBIDDEN)
  in OTHER_ROLES -> ...
  else -> userApiService.findById(id)
}
b
Well, the User has List<Role> so that complicates things
that’s why I tried to call “calculating” method in each branch
j
Yeah that's why I gave an example of using in.. You can create a static list on the companion object to store the set of validated roles to check membership
b
ok, thanks 🙂
j
One other thing you can do is create an extension function that is just a predicate.. it should basically check it and role and return true if both match. That way you can roll the two cases together.
Copy code
fun User.canLogin(id : String) : Boolean = id == this.id && this.hasMaxRole(Role.USER_ROLE)
This would be the alternative if you want to use
when {}
without an object.
Copy code
when {
  loggedInUser.canLogin(loggedInUser.id) -> ...
  loggedInUser.role in EnumSet.of(NO_ROLE, USER_ROLE) -> ...
  else -> ...
}
b
thanks for the solutionS 🙂 I’ll choose something which seems best to me