0

I want to reference the materialized value from the flow. Below is the code snippet, but its not compiling, error:

type mismatch;
 found   : (akka.NotUsed, scala.concurrent.Future[akka.Done])
 required: (Playground.DomainObj, scala.concurrent.Future[akka.Done])

Code:

import akka.actor.ActorSystem
import akka.stream.scaladsl._
import scala.concurrent.Future
import akka.NotUsed
import akka.Done

implicit val actorSystem = ActorSystem("example")

case class DomainObj(name: String, age: Int)

 val customFlow1:Flow[String,DomainObj,NotUsed] = Flow[String].map(s => {
    DomainObj(s, 50)
  })

  val customFlow2 = Flow[DomainObj].map(s => {
    s.age + 10
  })

val printAnySink: Sink[Any, Future[Done]] = Sink.foreach(println)

val c1 = Source.single("John").viaMat(customFlow1)(Keep.right).viaMat(customFlow2)(Keep.left).toMat(printAnySink)(Keep.both)

val res: (DomainObj, Future[Done]) = c1.run()

Find the code in playground: https://scastie.scala-lang.org/P9iSx49cQcaOZfKtVCzTPA

I want to reference the DomainObj after the stream completes/

yiksanchan
  • 1,890
  • 1
  • 13
  • 37

1 Answers1

0

The materialized value of a Flow[String, DomainObj, NotUsed] is NotUsed, not a DomainObj, therefore c1's materialized value is (NotUsed, Future[Done]).

It looks like the intent here is to capture the DomainObj which is created in customFlow1. That can be accomplished with

val customFlow1: Flow[String, DomainObj, Future[DomainObj]] =
  Flow[String]
    .map { s => DomainObj(s, 50) }
    .alsoTo(Sink.head)

val res: (Future[DomainObj], Future[Done]) = c1.run()

Note that Sink.head effectively requires that customFlow1 can only be used downstream of something that only emits once.

Levi Ramsey
  • 18,884
  • 1
  • 16
  • 30
  • Hi Levi, i tried with simple flow using String - val customFlow1: Flow[String, String, Future[String]] = Flow[String].map(abc => abc.toString). Getting the compilation issue as Expression of type Flow[String, String, NotUsed]#Repr[String] doesn't conform to expected type Flow[String, String, Future[String]]. Is Flow should be created with different form – Iyappan Sankaran Aug 16 '20 at 14:31
  • Yes, that clearly will not work because `Flow[String]` creates a `Flow[String, String, NotUsed]`: i.e. it has a materialized value of `NotUsed`, which is (by design) useless. Did you try the `alsoTo` method in my answer? – Levi Ramsey Aug 16 '20 at 14:55