title: Java Reactive stream how to map an object when the object being mapped is also needed on the next step of the stream
body: <p>I am using Java 11 and project Reactor (from Spring). I need to make a http call to a rest api (I can only make it once in the whole flow).
  With the response I need to compute two things:</p>
  <ol>
  <li>Check if a document exists in the database (mongodb). If it does not exists then create it and return it. Otherwise just return it.</li>
  <li>Compute some logic on the response and we are done.</li>
  </ol>
  <p>In pseudo code it is something like this:</p>
  <pre><code>public void computeData(String id) {
      httpClient.getData(id) // Returns a Mono&lt;Data&gt;
          .flatMap(data -&gt; getDocument(data.getDocumenId()))
           // Issue here is we need access to the data object consumed in the previous flatMap but at the same time we also need the document object we get from the previous flatMap
          .flatMap(document -&gt; calculateValue(document, data)) 
          .subscribe();
  }
  
  public Mono&lt;Document&gt; getDocument(String id) {
      // Check if document exists
      // If not create document
  
      return document;
  }
  
  public Mono&lt;Value&gt; calculateValue(Document doc, Data data) {
      // Do something...
      return value;
  }
  </code></pre>
  <p>The issue is that calculateValue needs the return value from http.getData but this was already consumed on the first flatMap but we also need the document object we get from the previous flatMap.</p>
  <p>I tried to solve this issue using <code>Mono.zip</code> like below:</p>
  <pre><code>public void computeData(String id) {
      final Mono&lt;Data&gt; dataMono = httpClient.getData(id);
  
      Mono.zip(
          new Mono&lt;Mono&lt;Document&gt;&gt;() {
              @Override
              public void subscribe(CoreSubscriber&lt;? super Mono&lt;Document&gt;&gt; actual) {
                  final Mono&lt;Document&gt; documentMono = dataMono.flatMap(data -&gt; getDocument(data.getDocumentId()))
                  actual.onNext(documentMono);
              }
          },
          new Mono&lt;Mono&lt;Value&gt;&gt;() {
              @Override
              public void subscribe(CoreSubscriber&lt;? super Mono&lt;Value&gt;&gt; actual) {
                  actual.onNext(dataMono);
              }
          }
      )
      .flatMap(objects -&gt; {
          final Mono&lt;Document&gt; documentMono = objects.getT1();
          final Mono&lt;Data&gt; dataMono = objects.getT2();
  
          return Mono.zip(documentMono, dataMono, (document, data) -&gt; calculateValue(document, data))
      })
  }
  </code></pre>
  <p>But this is executing the <code>httpClient.getData(id)</code> twice which goes against my constrain of only calling it once. I understand why it is being executed twice (I subscribe to it twice).</p>
  <p>Maybe my solution design can be improved somewhere but I do not see where. To me this sounds like a &quot;normal&quot; issue when designing reactive code but I could not find a suitable solution to it so far.</p>
  <p>My question is, how can accomplish this flow in a reactive and non blocking way and only making one call to the rest api?</p>
  <p>PS; I could add all the logic inside one single map but that would force me to subscribe to one of the Mono inside the map which is not recommended and I want to avoid following this approach.</p>
  <p>EDIT regarding @caco3 comment
  I need to subscribe inside the map because both <code>getDocument</code> and <code>calculateValue</code> methods return a <code>Mono</code>.</p>
  <p>So, if I wanted to put all the logic inside one single map it would be something like:</p>
  <pre><code>public void computeData(String id) {
      httpClient.getData(id)
          .map(data -&gt; getDocument(data).subscribe(s -&gt; calculateValue(s, data)))
          .subscribe();
  }
  </code></pre>