title: how to gracefully combine two Observables inside RXJS pipe
body: <p>I'm building a log viewer with Angular.</p>
  <p>When a user enters the page I need to load historical logs and start watching for new ones.
  User can filter logs with a simple form that emits a <code>query</code> object. Each time the <code>query</code> changes process is restarted (i.e. &quot;old&quot; results are evicted, new history is loaded and new &quot;live&quot; stream is started).</p>
  <p>I can do it in two ways but I'm not happy with either.</p>
  <p>The first one I find easier to understand but violates DRY principle.</p>
  <pre><code>const historicalLogs = this.querySubject
  .pipe(
    debounceTime(250),
    tap(() =&gt; this.logs = []),
    switchMap(
      query =&gt; this.deviceLogsService.getLogsBefore(query, moment())
    )
  );
  
  const futureLogs = this.querySubject
  .pipe(
    debounceTime(250),
    tap(() =&gt; this.logs = []),
    switchMap(
      query =&gt; timer(1000, 2000).pipe(mergeMap(t =&gt; this.deviceLogsService.getLogsAfter(query, moment())))
    )
  );
  
  merge(historicalLogs, futureLogs)
  .subscribe(newLogs =&gt; {
    this.logs.push(...newLogs);
    this.scrollToVeryBottom();
  });
  </code></pre>
  <p>The second doesn't violate DRY but I'm afraid that it will be hard to read/analyze in the future:</p>
  <pre><code>this.querySubject
    .pipe(
      debounceTime(250),
      tap(() =&gt; this.logs = []),
      switchMap(query =&gt; concat([
        this.deviceLogsService.getLogsBefore(query, moment()),
        timer(1000, 2000).pipe(mergeMap(t =&gt; this.deviceLogsService.getLogsAfter(query, moment())))
      ]).pipe(mergeAll()))
    )
    .subscribe(newLogs =&gt; {
      this.logs.push(...newLogs);
      this.scrollToVeryBottom();
    });
  </code></pre>
  <p>I'll appreciate any suggestions on implementing it in a more readable and elegant way.</p>