0

I have 4 functions, createUser, updateUser, deleteUser, listUser.

These 4 functions are all reactive.

How do I execute them by this sequence?

createUser->listUser(list created user)->updateUser->listUser(list updated user)>deleteUser->listUser

My createUser:

def createSomeUser() {
  var users = List[BSONDocument]()
  val user1 = BSONDocument(
    "firstName" -> "Kobe",
    "lastName" -> "Bryant",
    "Number" -> "8"
  )
  users = user1 :: users
  val enumerator = Enumerator.enumerate(users)
  val future = collection.bulkInsert(enumerator)
  future.onComplete {
    case Failure(e) => throw e
    case Success(lastError) => {
      println("All users were inserted to DB")
    }
  } 
}

My updateUser:

def updateAUser(firstName: String, number: Int)  {
  val selector = BSONDocument("firstName" -> firstName)

  val modifier = BSONDocument(
    "$set" -> BSONDocument(
      "Number" -> number))
  val futureUpdate = collection.update(selector, modifier)
  //get a future update
  futureUpdate.onComplete {
    case Failure(e) => throw e
    case Success(lastError) => {
      println("successfully Update user")
    }
  }
}

My deleteUser:

def deleteAUser(firstName: String) {
  val selector = BSONDocument(
    "firstName" -> firstName)
  val futureRemove = collection.remove(selector)
  futureRemove.onComplete {
    case Failure(e) => throw e
    case Success(lasterror) => {
      println("successfully removed users")
    }
  }
}

My listUser:

def listDocs() = {
  // Select all documents
  val query = BSONDocument()
  // select all fields
  val filter = BSONDocument(
    "lastName" -> 1,
    "firstName" -> 1,
    "Number" -> 1,
    "_id" -> 1)

  val fList = collection.
    find(query, filter).
    cursor[BSONDocument].
    collect[List]()

  fList.map { list =>
    list.foreach { doc =>
      println("found User: " + BSONDocument.pretty(doc))
    }
  }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
iamtd1983
  • 3
  • 1

1 Answers1

4

You can use flatMap but you will have to slightly change your function implementation because they don't return a future you can chain on, for example:

def createSomeUser(): Future[SomeType] = {
  (omitted for brevity)
  collection.bulkInsert(enumerator)
}

def updateAUser(firstName: String, number: Int): Future[SomeType] = {
   (omitted for brevity)
   collection.update(selector, modifier)
}

def deleteAUser(firstName: String): Future[SomeType] = {
  (omitted for brevity)
  collection.remove(selector)
}

They all now return a future with some value in it, now using flatMap you can chain executions:

createSomeUser().flatMap {
  created => updateAUser(someName, someNumber).flatMap {
    updatedUser => deleteAUser(created.getName).flatMap {
      deleted => // and so on...
    }
  }
}

Modifying the function implementations seems logic in this case, if you don't want to you will have most probably to wrap them in another future (when being invoked) or chain the function execution in the onComplete method, but this will hardcode the behaviour and it won't be possible to create custom invocation chains like the one I showed you.

Ende Neu
  • 15,581
  • 5
  • 57
  • 68