danbroooks danbroooks - 7 days ago 6
Scala Question

Scala - filter Some's that fail certain condition

Given a

UserRepository
:

class UserRepository {

val collection = Mongo.connect("users")

def findBy(key: String, value: String): Future[Option[User]] = {
collection.flatMap(
_.find(document(key -> value)).one[User]
)
}
}


And I want to write a
login
method:

def login(email: String, password: String): Future[Option[User]] = {
import scala.concurrent.ExecutionContext.Implicits.global

repo.findBy("email", email)
// .filter { user => BCrypt.checkpw(password, user.password) }
}


How would I write a mapping on the result of
findBy
to transform all
Some(user)
's into
None
's if they fail the test
BCrypt.checkpw(password, user.password)
? Is there some kind of transform I can do to turn any of the
Some
's that fail that check into
None
's?

Answer

Use collect and use the pattern matching guard to check the user. If user fails then return a None

findBy(key, value).collect {
  case Some(user) if ! BCrypt.checkpw(password, user.password) =>  None
}

Suggestion

It would be good to collect user which satisfy the condition this way your final output type would be Future[user] instead of Future[Option[User]]. Of course after the above collect your Future[Option[User]] would contain Some(user) where is the user is valid user.

findBy(key, value).collect {
  case Some(user) if BCrypt.checkpw(password, user.password) =>  user
}

The line gives only valid users and the final type would be Future[User] instead of Future[Option[User]]