title: How to optimally code an asynchronous action with optional subscription?
body: <p>I have a code which looks like this (not exactly, but close enough):</p>
  
  <pre class="lang-typescript prettyprint-override"><code>class Form&lt;R&gt; {
      restClient: {
          getById(id: number): Observable&lt;R&gt;;
      };
  
      createEmptyRecord(): R {
          return {};
      }
  
      load(id: number | null): Observable&lt;R&gt; {
          let loader: Observable&lt;R&gt;;
  
          if (id !== null) {
              loader = this.restClient.getById(id);
          } else {
              loader = Observable.of(this.createEmptyRecord());
          }
  
          const result = loader
              .do(record =&gt; {
                  // some side effect
              })
              .publishReplay(1);
  
          result.connect();
  
          return result;
      }
  }
  </code></pre>
  
  <p>So, <code>load()</code> is supposed to retrieve existing or empty record into form, and it also should allow to get notification when loading is done, but this is optional, and if nobody subscribes, it still should complete loading. Also, if notification observable is subscribed more than once, it should not initiate another loading process. E.g. all of the following should work:</p>
  
  <pre class="lang-typescript prettyprint-override"><code>const form = new Form&lt;Customer&gt;();
  
  // Load empty record, not interested in notification:
  form.load(null);
  
  // Load empty record, need notification:
  form.load(null).subscribe(console.log);
  
  // Load existing record, not interested in notification:
  form.load(1);
  
  // Load existing record, need notification:
  form.load(1).subscribe(console.log);
  
  // Load existing record, need several notifications,
  // but only one real REST call:
  const s = form.load(2);
  s.subscribe(console.log);
  s.subscribe(console.log);
  </code></pre>
  
  <p>The code above actually works (I hope it works correctly), but it feels very awkward.</p>
  
  <p>The question is: can it be written in a better way? Maybe there is some RxJS magic that does all of the above, but shorter, simpler?</p>